home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / oldwish / RCS / wishDisplay.c,v < prev    next >
Text File  |  1989-07-10  |  74KB  |  2,584 lines

  1. head     1.6;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    mgbaker:1.6; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.6
  10. date     89.01.19.16.53.10;  author mgbaker;  state Exp;
  11. branches ;
  12. next     1.5;
  13.  
  14. 1.5
  15. date     89.01.18.00.06.50;  author mgbaker;  state Exp;
  16. branches ;
  17. next     1.4;
  18.  
  19. 1.4
  20. date     89.01.11.11.30.59;  author mlgray;  state Exp;
  21. branches ;
  22. next     1.3;
  23.  
  24. 1.3
  25. date     88.11.03.19.44.38;  author mlgray;  state Exp;
  26. branches ;
  27. next     1.2;
  28.  
  29. 1.2
  30. date     88.11.02.14.49.54;  author mlgray;  state Exp;
  31. branches ;
  32. next     1.1;
  33.  
  34. 1.1
  35. date     88.10.03.12.47.25;  author mlgray;  state Exp;
  36. branches ;
  37. next     ;
  38.  
  39.  
  40. desc
  41. @X11: works pretty much now.
  42. @
  43.  
  44.  
  45. 1.6
  46. log
  47. @John added an extra parameter to Sx_CreateScrollbar, so I fixed this.
  48. @
  49. text
  50. @/* 
  51.  * wishDisplay.c --
  52.  *
  53.  *    Routines for layout and display for the file system flat display.
  54.  *
  55.  * Copyright 1987 Regents of the University of California
  56.  * All rights reserved.
  57.  * Permission to use, copy, modify, and distribute this
  58.  * software and its documentation for any purpose and without
  59.  * fee is hereby granted, provided that the above copyright
  60.  * notice appear in all copies.  The University of California
  61.  * makes no representations about the suitability of this
  62.  * software for any purpose.  It is provided "as is" without
  63.  * express or implied warranty.
  64.  */
  65.  
  66. #ifndef lint
  67. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishDisplay.c,v 1.5 89/01/18 00:06:50 mgbaker Exp $ SPRITE (Berkeley)";
  68. #endif not lint
  69.  
  70. typedef    int    Boolean;
  71. #define    FALSE    0
  72. #define TRUE    1
  73. #include <sys/types.h>
  74. #include <sys/stat.h>
  75. #include "time.h"
  76. #include <sys/dir.h>    /* included only for MAXNAMLEN */
  77. #include "string.h"
  78. #include "sx.h"
  79. #include "util.h"
  80. #include "monitorClient.h"
  81. #include "wishInt.h"
  82.  
  83. /*
  84.  * Include cursor declarations and definitions.
  85.  * flat.cursor defines the regular flat display cursor and wait.cursor defines
  86.  * the cursor used while the display is busy.
  87.  */
  88. #include "flat.cursor"
  89. #include "wait.cursor"
  90.  
  91. /*
  92.  * The flat cursor is the regular cursor when the display is
  93.  * idle.  The wait cursor indicates that the display is working
  94.  * away on something.  The regular cursor can be redefined by
  95.  * users, if they wish. (Well... sometime that will be possible...)
  96.  */
  97. static        Cursor        flatCursor = -1;
  98. static        Cursor        waitCursor = -1;
  99.  
  100. /* Default commands in the overall command table. */
  101. static    CmdInfo    commands[] = {
  102.     {"bind",        WishBindCmd},
  103.     {"changeDirectory",    WishChangeDirCmd},
  104.     {"quit",        WishQuitCmd},
  105.     {"close",        WishCloseCmd},
  106.     {"redraw",        WishRedrawCmd},
  107.     {"selection",    WishSelectionCmd},
  108.     {"resize",        WishResizeCmd},
  109.     {"toggleSelection",    WishToggleSelectionCmd},
  110.     {"toggleSelEntry",    WishToggleSelEntryCmd},
  111.     {"groupBind",    WishGroupBindCmd},
  112.     {"open",        WishOpenCmd},
  113.     {"sortFiles",    WishSortFilesCmd},
  114.     {"setFields",    WishChangeFieldsCmd},
  115.     {"defineGroup",    WishDefineGroupCmd},
  116.     {"changeGroup",    WishChangeGroupCmd},
  117.     {"pattern",        WishPatternCompareCmd},
  118.     {"menu",        WishMenuCmd},
  119.     {"exec",        WishExecCmd},
  120.     {(char *) NULL,    (int (*)()) NULL}
  121. };
  122.  
  123. /*
  124.  * Number of open windows, for graceful exit when we close them all.
  125.  */
  126. int    wishWindowCount = 0;
  127.  
  128. /*
  129. /*
  130.  * Used before defined.
  131.  */
  132. extern    void    GetColumnWidthInfo();
  133. extern    int    GetMaxEntryWidth();
  134. extern    void    FigureWindowSize();
  135.  
  136.  
  137.  
  138. /*
  139.  *----------------------------------------------------------------------
  140.  *
  141.  * WishCreate --
  142.  *
  143.  *    Create an wish window.
  144.  *
  145.  * Results:
  146.  *    A pointer to the created WishWindow structure, or NULL if the
  147.  *    call failed.
  148.  *
  149.  * Side effects:
  150.  *    A new wish window will be created and displayed.
  151.  *
  152.  *----------------------------------------------------------------------
  153.  */
  154. WishWindow *
  155. WishCreate(aWindow, dir)
  156.     WishWindow    *aWindow;    /* parent window */
  157.     char        *dir;        /* directory to start in */
  158. {
  159.     WishWindow    *newWindow;
  160.     struct    stat    dirAtts;
  161.     Tx_WindowInfo    info;
  162.     static        char    *args[] = {"/bin/csh", "-i", NULL};
  163.     XSizeHints        sizeHints;
  164.     XGCValues        gcValues;
  165.  
  166.     newWindow = (WishWindow *) malloc(sizeof (WishWindow));
  167.     if (dir != NULL) {
  168.     /* quick hack until i fix selection problems */
  169.     if (dir[strlen(dir) - 1] == ' ') {
  170.         dir[strlen(dir) - 1] = '\0';
  171.     }
  172.     if (Util_CanonicalDir(dir, NULL, newWindow->dir) == NULL) {
  173.         /* error message returned in newWindow->dir */
  174.         /* if null, then we were called from main() anyway */
  175.         if (aWindow->interp == NULL) {
  176.         Sx_Panic(wishDisplay, newWindow->dir);
  177.         }
  178.         strcpy(aWindow->interp->result, newWindow->dir);
  179.         free(newWindow);
  180.         return NULL;
  181.     }
  182.     } else {
  183.     strcpy(newWindow->dir, aWindow->dir);
  184.     }
  185.     if (lstat(newWindow->dir, &dirAtts)
  186.         != 0) {
  187.     /* if null, then we were called from main() anyway */
  188.     if (aWindow->interp == NULL) {
  189.         sprintf(wishErrorMsg,
  190.             "Can't get attributes for %s.  Maybe it doesn't exist",
  191.             newWindow->dir);
  192.         Sx_Panic(wishDisplay, wishErrorMsg);
  193.     }
  194.     sprintf(aWindow->interp->result,
  195.         "Can't get attributes for %s.  Maybe it doesn't exist",
  196.         newWindow->dir);
  197.     free(newWindow);
  198.     return NULL;
  199.     }
  200.     /* Put name of dir in the editable string for the title display window */
  201.     strcpy(newWindow->editDir, newWindow->dir);
  202.  
  203.     if ((dirAtts.st_mode & S_IFMT) != S_IFDIR) {    /* not a directory */
  204.     if (aWindow->interp == NULL) {
  205.         sprintf(wishErrorMsg, "%s is not a directory", newWindow->dir);
  206.         Sx_Panic(wishDisplay, wishErrorMsg);
  207.     }
  208.     sprintf(aWindow->interp->result, "%s is not a directory",
  209.         newWindow->dir);
  210.     free(newWindow);
  211.     return NULL;
  212.     }
  213.      
  214.     if (chdir(newWindow->dir) != 0) {
  215.     if (aWindow->interp == NULL) {
  216.         sprintf(wishErrorMsg,
  217.             "Couldn't change directories to %s", newWindow->dir);
  218.         Sx_Panic(wishDisplay, wishErrorMsg);
  219.     }
  220.     sprintf(aWindow->interp->result,
  221.         "Couldn't change directories to %s", newWindow->dir);
  222.     free(newWindow);
  223.     return NULL;
  224.     }
  225.     strcpy(wishCurrentDirectory, newWindow->dir);
  226.  
  227.     newWindow->foreground = aWindow->foreground;
  228.     newWindow->background = aWindow->background;
  229.     newWindow->selection = aWindow->selection;
  230.     newWindow->border = aWindow->border;
  231.     newWindow->borderWidth = aWindow->borderWidth;
  232.     newWindow->fontPtr = aWindow->fontPtr;
  233.     newWindow->titleForeground = aWindow->titleForeground;
  234.     newWindow->titleBackground = aWindow->titleBackground;
  235.     newWindow->titleBorder = aWindow->titleBorder;
  236.     newWindow->titleFontPtr = aWindow->titleFontPtr;
  237.     newWindow->txForeground = aWindow->txForeground;
  238.     newWindow->txBackground = aWindow->txBackground;
  239.     newWindow->txBorder = aWindow->txBorder;
  240.     newWindow->menuForeground = aWindow->menuForeground;
  241.     newWindow->menuBackground = aWindow->menuBackground;
  242.     newWindow->sortForeground = aWindow->sortForeground;
  243.     newWindow->sortBackground = aWindow->sortBackground;
  244.     newWindow->fieldsForeground = aWindow->fieldsForeground;
  245.     newWindow->fieldsBackground = aWindow->fieldsBackground;
  246.     newWindow->entryForeground = aWindow->entryForeground;
  247.     newWindow->entryBackground = aWindow->entryBackground;
  248.     newWindow->scrollForeground = aWindow->scrollForeground;
  249.     newWindow->scrollBackground = aWindow->scrollBackground;
  250.     newWindow->scrollElevator = aWindow->scrollElevator;
  251.     newWindow->geometry = aWindow->geometry;
  252.     newWindow->firstElement = UNINITIALIZED;
  253.     newWindow->numGroups = UNINITIALIZED;
  254.     newWindow->numHiddenGroups = 0;
  255.     newWindow->hideEmptyGroupsP = aWindow->hideEmptyGroupsP;
  256.     newWindow->dontDisplayChangesP = FALSE;
  257.     newWindow->notifierP = FALSE;
  258.  
  259.     /*
  260.      * Create the first window and subwindows and use the window id to
  261.      * identify the application's data.
  262.      */
  263.     if (newWindow->geometry != NULL) {
  264.     (void) XParseGeometry(newWindow->geometry, &sizeHints.x, &sizeHints.y,
  265.         &sizeHints.width, &sizeHints.height);
  266.     }
  267.     newWindow->surroundingWindow = XCreateSimpleWindow(wishDisplay,
  268.         DefaultRootWindow(wishDisplay), sizeHints.x, sizeHints.y,
  269.     sizeHints.width, sizeHints.height, newWindow->borderWidth,
  270.         newWindow->border, newWindow->background);
  271.     if (newWindow->surroundingWindow == 0) {
  272.     if (aWindow->interp == NULL) {
  273.         Sx_Panic(wishDisplay, "Couldn't create a new window.");
  274.     }
  275.     sprintf(aWindow->interp->result, "couldn't create a new window");
  276.     goto cleanUp;
  277.     }
  278.     /* for window icon */
  279.     XStoreName(wishDisplay, newWindow->surroundingWindow, newWindow->dir);
  280.  
  281.     /* Create textGc */
  282.     gcValues.foreground = aWindow->foreground;
  283.     gcValues.background = aWindow->background;
  284.     gcValues.font = newWindow->fontPtr->fid;
  285.     newWindow->textGc = XCreateGC(wishDisplay, newWindow->surroundingWindow,
  286.         GCForeground | GCBackground | GCFont, &gcValues);
  287.     /* Create reverseGc */
  288.     gcValues.foreground = aWindow->background;
  289.     gcValues.background = aWindow->foreground;
  290.     gcValues.font = newWindow->fontPtr->fid;
  291.     newWindow->reverseGc = XCreateGC(wishDisplay,
  292.         newWindow->surroundingWindow,
  293.         GCForeground | GCBackground | GCFont, &gcValues);
  294.  
  295.  
  296.     /*
  297.      * To get a nice divider between the title/entry window and the display
  298.      * window, create the windows with no border and create a divider as
  299.      * a separate, thin, window.  The title window is also a command entry
  300.      * window which is why I don't just use Sx_TitleCreate().
  301.      */
  302.     newWindow->titleWindow = Sx_CreatePacked(wishDisplay,
  303.         newWindow->surroundingWindow,
  304.         SX_TOP, Sx_DefaultHeight(wishDisplay, newWindow->titleFontPtr),
  305.         0, 0, newWindow->titleBorder, (Window) 0,
  306.         newWindow->titleBackground);
  307.     if (newWindow->titleWindow == 0) {
  308.     if (aWindow->interp == NULL) {
  309.         Sx_Panic(wishDisplay, "Couldn't create title window.");
  310.     }
  311.     sprintf(aWindow->interp->result, "couldn't create title window");
  312.     goto cleanUp;
  313.     }
  314.     /* Put "title" in window. */
  315.     Sx_EntryMake(wishDisplay, newWindow->titleWindow, "Directory:  ",
  316.         newWindow->titleFontPtr, newWindow->titleForeground,
  317.         newWindow->titleBackground, newWindow->editDir,
  318.         sizeof (newWindow->editDir));
  319.  
  320.     newWindow->txOutsideWindow = Sx_CreatePacked(wishDisplay,
  321.         newWindow->surroundingWindow,
  322.         SX_BOTTOM, 8 * Sx_DefaultHeight(wishDisplay, newWindow->fontPtr),
  323.         0, 0, newWindow->txBorder, (Window) 0, newWindow->txBackground);
  324.  
  325.     /* Unless i can get this info from Sx, how else can I do it? */
  326.     {
  327.     Window    dummy1;
  328.     int    x, y, width, height, border_width, dummy2;
  329.  
  330.     if (XGetGeometry(wishDisplay, newWindow->txOutsideWindow, &dummy1,
  331.         &x, &y, &width, &height, &border_width, &dummy2) == 0) {
  332.         Sx_Panic(wishDisplay, "Couldn't get tx window geometry.");
  333.     }
  334.     info.width = width;
  335.     }
  336.  
  337.     /* Create first divider */
  338.     newWindow->divider1Window = Sx_CreatePacked(wishDisplay,
  339.         newWindow->surroundingWindow,
  340.         SX_TOP, 1, 0, 0, newWindow->border, (Window) 0, newWindow->border);
  341.     if (newWindow->divider1Window == 0) {
  342.     if (aWindow->interp == NULL) {
  343.         Sx_Panic(wishDisplay,
  344.             "Couldn't create the first border between windows.");
  345.     }
  346.     sprintf(aWindow->interp->result,
  347.         "couldn't create the first border between windows");
  348.     goto cleanUp;
  349.     }
  350.     newWindow->menuBar = Sx_CreatePacked(wishDisplay,
  351.         newWindow->surroundingWindow, SX_TOP,
  352.         Sx_DefaultHeight(wishDisplay, newWindow->titleFontPtr), 0, 0,
  353.         newWindow->menuForeground, (Window) 0, newWindow->menuBackground);
  354.     /* Create next divider */
  355.     newWindow->divider2Window = Sx_CreatePacked(wishDisplay,
  356.         newWindow->surroundingWindow,
  357.         SX_TOP, 1, 0, 0, newWindow->border, (Window) 0, newWindow->border);
  358.     if (newWindow->divider2Window == 0) {
  359.     if (aWindow->interp == NULL) {
  360.         Sx_Panic(wishDisplay,
  361.             "Couldn't create the second border between windows.");
  362.     }
  363.     sprintf(aWindow->interp->result,
  364.         "couldn't create the second border between windows");
  365.     goto cleanUp;
  366.     }
  367.     newWindow->sortWindow = Sx_TitleCreate(wishDisplay,
  368.     newWindow->surroundingWindow,
  369.     SX_TOP, Sx_DefaultHeight(wishDisplay, newWindow->fontPtr), 0,
  370.     newWindow->fontPtr,
  371.     newWindow->sortForeground, newWindow->sortBackground,
  372.     newWindow->sortBackground, NULL, NULL, NULL);
  373.     if (newWindow->sortWindow == 0) {
  374.     if (aWindow->interp == NULL) {
  375.         Sx_Panic(wishDisplay, "Couldn't create the sort window.");
  376.     }
  377.     sprintf(aWindow->interp->result, "couldn't create the sort window");
  378.     goto cleanUp;
  379.     }
  380.     newWindow->divider3Window = Sx_CreatePacked(wishDisplay,
  381.         newWindow->surroundingWindow,
  382.         SX_TOP, 1, 0, 0, newWindow->border, (Window) 0, newWindow->border);
  383.     if (newWindow->divider3Window == 0) {
  384.     if (aWindow->interp == NULL) {
  385.         Sx_Panic(wishDisplay,
  386.             "Couldn't create the third border between windows.");
  387.     }
  388.     sprintf(aWindow->interp->result,
  389.         "couldn't create the third border between windows");
  390.     goto cleanUp;
  391.     }
  392.     newWindow->fieldsWindow = Sx_TitleCreate(wishDisplay,
  393.     newWindow->surroundingWindow,
  394.     SX_TOP, Sx_DefaultHeight(wishDisplay, newWindow->fontPtr), 0,
  395.     newWindow->fontPtr,
  396.     newWindow->fieldsForeground, newWindow->fieldsBackground,
  397.     newWindow->fieldsBackground, NULL, NULL, NULL);
  398.     if (newWindow->fieldsWindow == 0) {
  399.     if (aWindow->interp == NULL) {
  400.         Sx_Panic(wishDisplay, "Couldn't create the fields window.");
  401.     }
  402.     sprintf(aWindow->interp->result, "couldn't create fields window");
  403.     goto cleanUp;
  404.     }
  405.     /* Create next divider */
  406.     newWindow->divider4Window = Sx_CreatePacked(wishDisplay,
  407.         newWindow->surroundingWindow,
  408.         SX_TOP, 1, 0, 0, newWindow->border, (Window) 0, newWindow->border);
  409.     if (newWindow->divider4Window == 0) {
  410.     if (aWindow->interp == NULL) {
  411.         Sx_Panic(wishDisplay,
  412.             "Couldn't create the fourth border between windows.");
  413.     }
  414.     sprintf(aWindow->interp->result,
  415.         "couldn't create the fourth border between windows");
  416.     goto cleanUp;
  417.     }
  418.  
  419.     /*
  420.      * Is 1 really the size I want for the scrollbar border?
  421.      */
  422.     newWindow->scrollWindow = Sx_ScrollbarCreate(wishDisplay,
  423.         newWindow->surroundingWindow,
  424.         SX_RIGHT, 1, newWindow->scrollForeground,
  425.         newWindow->scrollBackground,
  426.         newWindow->scrollElevator, newWindow->border, WishScroll,
  427.         newWindow);
  428.     if (newWindow->scrollWindow == 0) {
  429.     if (aWindow->interp == NULL) {
  430.         Sx_Panic(wishDisplay, "Couldn't create the scroll bar.");
  431.     }
  432.     sprintf(aWindow->interp->result, "couldn't create the scrollbar");
  433.     goto cleanUp;
  434.     }
  435.     /* Create next divider */
  436.     newWindow->divider5Window = Sx_CreatePacked(wishDisplay,
  437.         newWindow->surroundingWindow, SX_RIGHT, 1, 0, 0, newWindow->border,
  438.         (Window) 0, newWindow->border);
  439.     if (newWindow->divider5Window == 0) {
  440.     if (aWindow->interp == NULL) {
  441.         Sx_Panic(wishDisplay,
  442.             "Couldn't create the fifth border between windows.");    
  443.     }
  444.     sprintf(aWindow->interp->result,
  445.         "couldn't create the fifth border between windows");
  446.     goto cleanUp;
  447.     }
  448. #ifdef NOTDEF
  449. /* what was this for in X10? */
  450.     tx_RegisterPtr = FALSE;
  451. #endif /* NOTDEF */
  452.     info.source = NULL;
  453.     info.fontPtr = newWindow->fontPtr;
  454.     /*
  455.      * outside of tx window is 8 * Sx_DefaultHeight, but inside is more or
  456.      * less 4 times, if you count title bars, etc.
  457.      */
  458.     info.height = 4 * Sx_DefaultHeight(wishDisplay, newWindow->fontPtr);
  459.     info.foreground = newWindow->txForeground;
  460.     info.background = newWindow->txBackground;
  461.     info.border = newWindow->txBorder;
  462.     info.sbForeground = newWindow->scrollForeground;
  463.     info.sbBackground = newWindow->scrollBackground;
  464.     info.sbElevator = newWindow->scrollElevator;
  465.     info.titleForeground = newWindow->titleForeground;
  466.     info.titleBackground = newWindow->titleBackground;
  467.     info.titleStripe = newWindow->titleForeground;
  468.     info.flags = MX_RAW;
  469.     Tx_GetTermAndTitle(newWindow->txOutsideWindow, NULL, &info);
  470.     XStoreName(wishDisplay, newWindow->txOutsideWindow, info.title);
  471.     Tx_Make(wishDisplay, newWindow->txOutsideWindow, &info, Tx_InputProc,
  472.         (ClientData) NULL);
  473.     Tx_Shell(wishDisplay, newWindow->txOutsideWindow, &info, args);
  474.     /* Create next divider */
  475.     newWindow->divider6Window = Sx_CreatePacked(wishDisplay,
  476.         newWindow->surroundingWindow,
  477.         SX_BOTTOM, 1, 0, 0, newWindow->border, (Window) 0,
  478.         newWindow->border);
  479.     if (newWindow->divider6Window == 0) {
  480.     if (aWindow->interp == NULL) {
  481.         Sx_Panic(wishDisplay,
  482.             "Couldn't create the sixth border between windows.");
  483.     }
  484.     sprintf(aWindow->interp->result,
  485.         "couldn't create the sixth border between windows");
  486.     goto cleanUp;
  487.     }
  488.     /* Create display subwindow */
  489.     newWindow->displayWindow = Sx_CreatePacked(wishDisplay,
  490.         newWindow->surroundingWindow,
  491.         SX_TOP, 0, 1, 0, newWindow->border, (Window) 0,
  492.         newWindow->background);
  493.     if (newWindow->displayWindow == 0) {
  494.     if (aWindow->interp == NULL) {
  495.         Sx_Panic(wishDisplay, "Couldn't create the display window.");
  496.     }
  497.     sprintf(aWindow->interp->result, "couldn't create display window");
  498. cleanUp:
  499.     if (newWindow->surroundingWindow != NULL) {
  500.         XDestroySubwindows(wishDisplay, newWindow->surroundingWindow);
  501.         XDestroyWindow(wishDisplay, newWindow->surroundingWindow);
  502.     }
  503.     free(newWindow);
  504.     return NULL;
  505.     }
  506.  
  507.     /*
  508.      * Increment the window reference count and enter the window information
  509.      * structure into the wishWindowContext.
  510.      */
  511.     wishWindowCount++;
  512.     XSaveContext(wishDisplay, newWindow->surroundingWindow,
  513.         (caddr_t) wishWindowContext, newWindow);
  514.  
  515.     /*
  516.      * Start up the display with newWindow->dir as the directory of the display.
  517.      * WishInit() will map the surrounding window.  It may first change
  518.      * its size.
  519.      */
  520.     WishInit(newWindow);
  521.     newWindow->firstElement = 1;    /* start displaying from beginning */
  522.     /*
  523.      * WishSetPositions() and WishRedraw() will be called as a result
  524.      * of the handlers, since Sx stuff generates an ExposureMask event.
  525.      * This means I don't need to call them here explicitly.
  526.      */
  527.  
  528.     /* For the handlers, should I pass the window or newWindow as clientData? */
  529.     Sx_HandlerCreate(wishDisplay, newWindow->surroundingWindow,
  530.         EnterWindowMask, WishHandleEnterEvent, newWindow);
  531.     /*
  532.      * Select these button events in the display window, but pass the
  533.      * surrounding window to the handlers.
  534.      */
  535.     Sx_HandlerCreate(wishDisplay, newWindow->displayWindow, ButtonPressMask
  536.         | PointerMotionMask | LeaveWindowMask, WishMouseEvent,
  537.         newWindow->surroundingWindow);
  538.     /*
  539.      * Select these key press events in the title subwindow, but
  540.      * pass the surrounding window to the handlers.
  541.      */
  542.     Sx_HandlerCreate(wishDisplay, newWindow->titleWindow, KeyPressMask,
  543.         WishEditDir, newWindow->surroundingWindow);
  544.  
  545.     /*
  546.      * Move this further up before various datastructures are created?
  547.      * Add dir to wish's list.  Use windowID to match this dir for this
  548.      * window.
  549.      */
  550.     if (!MonClient_AddDir(newWindow->dir, newWindow->surroundingWindow)) {
  551.     /* What should I do here? */
  552.     Sx_Panic(wishDisplay,
  553.         "File system monitor failed in WishCreate().");
  554.     }
  555.  
  556.     return newWindow;
  557. }
  558.  
  559.  
  560. /*
  561.  *----------------------------------------------------------------------
  562.  *
  563.  * WishInit --
  564.  *
  565.  *    Initialize a new flat display.
  566.  *
  567.  * Results:
  568.  *    None.
  569.  *
  570.  * Side effects:
  571.  *    Lots.
  572.  *
  573.  *----------------------------------------------------------------------
  574.  */
  575. void
  576. WishInit(aWindow)
  577.     WishWindow    *aWindow;    /* info for this instance of display */
  578. {
  579.     XColor    cursorForeground;
  580.     XColor    cursorBackground;
  581.     Pixmap    source;
  582.  
  583.     cursorForeground.pixel = aWindow->background;
  584.     cursorBackground.pixel = aWindow->foreground;
  585.     XQueryColor(wishDisplay, DefaultColormap(wishDisplay,
  586.         DefaultScreen(wishDisplay)), &cursorForeground);
  587.     XQueryColor(wishDisplay, DefaultColormap(wishDisplay,
  588.         DefaultScreen(wishDisplay)), &cursorBackground);
  589.     if (flatCursor == -1) {
  590.     source = XCreateBitmapFromData(wishDisplay,
  591.         DefaultRootWindow(wishDisplay), flatCursor_bits,
  592.         flatCursor_width, flatCursor_height);
  593.     flatCursor = XCreatePixmapCursor(wishDisplay, source, None,
  594.         &cursorBackground, &cursorForeground, flatCursor_x_hot,
  595.         flatCursor_y_hot);
  596.     XFreePixmap(wishDisplay, source);
  597.     }
  598.     /* We'll need the cursor later - don't free it */
  599.     XDefineCursor(wishDisplay, aWindow->displayWindow, flatCursor);
  600.  
  601.     /*
  602.      * When work is being done, the cursor changes to the "wait" cursor.
  603.      */
  604.     if (waitCursor == -1) {
  605.     source = XCreateBitmapFromData(wishDisplay,
  606.         DefaultRootWindow(wishDisplay), waitCursor_bits,
  607.         waitCursor_width, waitCursor_height);
  608.     waitCursor = XCreatePixmapCursor(wishDisplay, source, None,
  609.         &cursorBackground, &cursorForeground, waitCursor_x_hot,
  610.         waitCursor_y_hot);
  611.     XFreePixmap(wishDisplay, source);
  612.     }
  613.     {
  614.     Window    dummy1;
  615.     int    x, y, width, height, border_width, dummy2;
  616.  
  617.     if (XGetGeometry(wishDisplay, aWindow->displayWindow, &dummy1,
  618.         &x, &y, &width, &height, &border_width, &dummy2) == 0) {
  619.         Sx_Panic(wishDisplay, "Couldn't get display window geometry.");
  620.     }
  621.     WishSetWindowAndRowInfo(aWindow, height, width);
  622.     }
  623.  
  624.     /* initialize data structures */
  625.     aWindow->displayInstructions = 0;
  626.     aWindow->sortingInstructions = 0;
  627.     aWindow->maxNameLength = 0;        /* longest length name */
  628.     aWindow->maxEntryWidth = 0;        /* longest entry */
  629.     aWindow->numElements = -1;        /* >= 0 means already initialized */
  630.     aWindow->totalDisplayEntries = 0;
  631.     /* numRows and rowHeight set above */
  632.     aWindow->firstElement = aWindow->lastElement = -1;
  633.     /* 8 columns is probably more than plenty to start out with. */
  634.     aWindow->columns = (WishColumn *) malloc(8 * sizeof (WishColumn));
  635.     aWindow->maxColumns = 8;
  636.     aWindow->usedCol = -1;
  637.     if (wishResizeP) {
  638.     aWindow->resizeP = TRUE;
  639.     } else {
  640.     aWindow->resizeP = FALSE;
  641.     }
  642.     if (wishPickSizeP) {
  643.     aWindow->pickSizeP = TRUE;
  644.     } else {
  645.     aWindow->pickSizeP = FALSE;
  646.     }
  647.     if (wishShowEmptyGroupsP) {
  648.     aWindow->hideEmptyGroupsP = FALSE;
  649.     } else {
  650.     aWindow->hideEmptyGroupsP = TRUE;
  651.     }
  652.     aWindow->groupList = NULL;
  653.     aWindow->selectionList = NULL;
  654.     /* create command bindings table and tcl interpreter. */
  655.     WishCmdTableInit(&(aWindow->cmdTable), &(aWindow->interp),
  656.         commands, (ClientData) aWindow);
  657.  
  658.     WishSourceConfig(aWindow);
  659.  
  660.     /* figure initial size */
  661.     if (aWindow->pickSizeP) {
  662.     aWindow->pickSizeP = FALSE;        /* only the first time */
  663.     /* This next will cause the surrounding window to change shape */
  664.     FigureWindowSize(aWindow, GetMaxEntryWidth(aWindow));
  665.     }
  666.     /* map surrounding  window */
  667.     XMapWindow(wishDisplay, aWindow->surroundingWindow);
  668.  
  669.     Sx_HandlerCreate(wishDisplay, aWindow->displayWindow,
  670.         ExposureMask | StructureNotifyMask,
  671.         WishHandleDrawingEvent, (ClientData) aWindow);
  672.     Sx_HandlerCreate(wishDisplay, aWindow->displayWindow, KeyPressMask,
  673.         WishKeyProc, (ClientData) aWindow);
  674.     Sx_HandlerCreate(wishDisplay, aWindow->menuBar, EnterWindowMask,
  675.         WishMenuEntryProc, (ClientData) aWindow);
  676.  
  677.     return;
  678. }
  679.  
  680.  
  681. /*
  682.  *----------------------------------------------------------------------
  683.  *
  684.  * WishSetPositions --
  685.  *
  686.  *    Figure out and set the coordinates of things to display.
  687.  *    This means sticking things in columns and determining when
  688.  *    the display would be filled up.
  689.  *
  690.  * Results:
  691.  *    None.
  692.  *
  693.  * Side effects:
  694.  *    The coordinates change.  A new column or so may be allocated.
  695.  *
  696.  *----------------------------------------------------------------------
  697.  */
  698. void
  699. WishSetPositions(aWindow)
  700.     WishWindow    *aWindow;
  701. {
  702.     WishGroup        *tmpGroupPtr = NULL;
  703.     WishFile        *tmpFilePtr = NULL;
  704.     WishColumn    *newColumns;
  705.     Boolean        spaceP = FALSE;
  706.     int            numCols;
  707.     int            i;
  708.     int            maxEntryWidth;
  709.     int            numMappedHeaders = 0;    /* Use at end for ignoring
  710.                          * extra expose events. */
  711. #ifdef SCROLL_DEBUG
  712.     fprintf(stderr, "Entered WishSetPositions:\n");
  713.     fprintf(stderr, "\tfirstElement is %d\n",
  714.         aWindow->firstElement);
  715.     fprintf(stderr, "\tlastElement is %d\n",
  716.         aWindow->lastElement);
  717.     fprintf(stderr, "\tnumElements is %d\n",
  718.         aWindow->numElements);
  719.     fprintf(stderr, "\tcolumns used is %d\n",
  720.         aWindow->usedCol + 1);
  721. #endif SCROLL_DEBUG
  722.  
  723.     if (aWindow->notifierP) {
  724.     return;
  725.     }
  726.     if (aWindow->firstElement <= 0) {
  727.     sprintf(wishErrorMsg,
  728.         "Entered WishSetPositions with firstElement = %d",
  729.         aWindow->firstElement);
  730.     Sx_Panic(wishDisplay, wishErrorMsg);
  731.     }
  732.     /*
  733.      * Avoid exposure events from creating and resizing windows below.  The
  734.      * window will be remapped later causing WishRedraw() to be called.
  735.      */
  736.     XUnmapWindow(wishDisplay, aWindow->displayWindow);
  737.  
  738.     maxEntryWidth = GetMaxEntryWidth(aWindow);
  739.     if (aWindow->resizeP) {
  740.     FigureWindowSize(aWindow, maxEntryWidth);
  741.     }
  742.     GetColumnWidthInfo(aWindow, maxEntryWidth, &(aWindow->columnWidth),
  743.         &numCols);
  744. #ifdef SCROLL_DEBUG
  745.     fprintf(stderr, "Number of columns to use is %d\n", numCols);
  746. #endif SCROLL_DEBUG
  747.  
  748.     /* do we need to allocate more columns? */
  749.     if (numCols > aWindow->maxColumns) {
  750.     newColumns = (WishColumn *)
  751.         malloc(aWindow->maxColumns * 2 * sizeof (WishColumn));
  752.     for (i = 0; i < aWindow->maxColumns; i++) {
  753.         newColumns[i] = aWindow->columns[i];
  754.     }
  755.     free(aWindow->columns);
  756.     aWindow->columns = newColumns;
  757.     aWindow->maxColumns *= 2;
  758.     }
  759.  
  760.     /* get to the first one to display */
  761.     i = 0;
  762.     aWindow->lastElement = 0;
  763.     for (tmpGroupPtr = aWindow->groupList; tmpGroupPtr != NULL;
  764.         tmpGroupPtr = tmpGroupPtr->nextPtr) {
  765.     /*
  766.      * Check if we've hit the right element to start displaying at.  If
  767.      * so, then check that either it's okay to display headers for empty
  768.      * groups, or else this isn't an empty group.
  769.      */
  770.     if ((i + 1 == aWindow->firstElement) && (!aWindow->hideEmptyGroupsP ||
  771.         tmpGroupPtr->fileList != NULL)) {
  772.         break;
  773.     }
  774.     tmpGroupPtr->myColumn = -1;
  775.     tmpGroupPtr->x = tmpGroupPtr->y = -1;
  776.     if (tmpGroupPtr->headerWindow != UNINITIALIZED) {
  777.         XUnmapWindow(wishDisplay, tmpGroupPtr->headerWindow);
  778.     }
  779.     /* only increment if this was a visible header */
  780.     if (!aWindow->hideEmptyGroupsP || tmpGroupPtr->fileList != NULL) {
  781.         i++;
  782.     }
  783.     for (tmpFilePtr = tmpGroupPtr->fileList; tmpFilePtr != NULL;
  784.         tmpFilePtr = tmpFilePtr->nextPtr) {
  785.         if (i + 1 == aWindow->firstElement) {
  786.         break;
  787.         } else {
  788.         tmpFilePtr->x = tmpFilePtr->y = -1;
  789.         tmpFilePtr->myColumn = -1;
  790.         }
  791.         i++;
  792.     }
  793.     if (tmpFilePtr != NULL) {
  794.         break;    /* we found it */
  795.     }
  796.     if (i+1 == aWindow->firstElement) {
  797.         /*
  798.          * The next thing we would display is a space followed by a
  799.          * group header, unless the group is an empty group and we aren't
  800.          * supposed to be displaying empty groups...
  801.          */
  802.         if (!aWindow->hideEmptyGroupsP || (tmpGroupPtr->nextPtr != NULL &&
  803.             tmpGroupPtr->nextPtr->fileList != NULL)) {
  804.         spaceP = TRUE;
  805.         tmpGroupPtr = tmpGroupPtr->nextPtr;
  806.         break;
  807.         }
  808.     }
  809.     /* only increment if this would be a space after a visible header */
  810.     if (!aWindow->hideEmptyGroupsP || tmpGroupPtr->fileList != NULL) {
  811.         i++;
  812.     }
  813.     }
  814.     if (tmpGroupPtr == NULL) {        /* all groups were empty, no display */
  815.     goto finished;
  816.     }
  817.     /* We've figured out what to start displaying */
  818.  
  819.     /* Now fill in the columns */
  820.     for (aWindow->usedCol = 0; aWindow->usedCol < numCols; aWindow->usedCol++) {
  821.     aWindow->columns[aWindow->usedCol].x =
  822.         aWindow->usedCol * aWindow->columnWidth;
  823.  
  824.     for (i = 0; i < aWindow->numRows; i++) {
  825.         if (spaceP == TRUE) {
  826.         spaceP = FALSE;
  827.         continue;
  828.         }
  829.         /*
  830.          * If tmpFilePtr is NULL, we have come to a new group header.
  831.          */
  832.         if (tmpFilePtr == NULL) {
  833.         /* set tmpFilePtr to fileList for this group. */
  834.  
  835.         tmpFilePtr = tmpGroupPtr->fileList;
  836.         if (aWindow->hideEmptyGroupsP && tmpFilePtr == NULL) {
  837.             if (tmpGroupPtr->headerWindow != UNINITIALIZED) {
  838.             XUnmapWindow(wishDisplay, tmpGroupPtr->headerWindow);
  839.             }
  840.             tmpGroupPtr = tmpGroupPtr->nextPtr;
  841.             i--;    /* so that i is the same next iteration */
  842.             if (tmpGroupPtr == NULL) {    /* end of groups */
  843.             goto finished;
  844.             }
  845.             continue;
  846.         }
  847.         tmpGroupPtr->myColumn = aWindow->usedCol;
  848.         tmpGroupPtr->x = aWindow->columns[aWindow->usedCol].x;
  849.         tmpGroupPtr->y = i * aWindow->rowHeight;
  850.         strcpy(tmpGroupPtr->editHeader, tmpGroupPtr->rule);
  851.         if (tmpGroupPtr->headerWindow == UNINITIALIZED) {
  852.             /* Need to create a header window */
  853. /* necessary? */    tmpGroupPtr->entry_width = aWindow->columnWidth;
  854.             tmpGroupPtr->entry_x = tmpGroupPtr->x;
  855.             tmpGroupPtr->entry_y = tmpGroupPtr->y;
  856.             /*
  857.              * If it's the first column, then start it one pixel
  858.              * to the left, so that borders overlap.
  859.              */
  860.             if (tmpGroupPtr->myColumn > 0) {
  861.             tmpGroupPtr->headerWindow =
  862.                 Sx_EntryCreate(wishDisplay,
  863.                 aWindow->displayWindow,
  864.                 tmpGroupPtr->x, tmpGroupPtr->y - 1,
  865.                 aWindow->columnWidth - 1,
  866.                 aWindow->rowHeight - 1, 1, NULL,
  867.                 aWindow->fontPtr, aWindow->entryForeground,
  868.                 aWindow->entryBackground,
  869.                 tmpGroupPtr->editHeader,
  870.                 sizeof (tmpGroupPtr->editHeader));
  871.             } else {
  872.             tmpGroupPtr->headerWindow =
  873.                 Sx_EntryCreate(wishDisplay,
  874.                 aWindow->displayWindow,
  875.                 tmpGroupPtr->x - 1, tmpGroupPtr->y - 1,
  876.                 aWindow->columnWidth,
  877.                 aWindow->rowHeight - 1, 1, NULL,
  878.                 aWindow->fontPtr, aWindow->entryForeground,
  879.                 aWindow->entryBackground,
  880.                 tmpGroupPtr->editHeader,
  881.                 sizeof (tmpGroupPtr->editHeader));
  882.             }
  883.             if (tmpGroupPtr->headerWindow == 0) {
  884.             Sx_Panic(wishDisplay,
  885.                 "You've run out of windows?!  Farewell!");
  886.             }
  887.             XSaveContext(wishDisplay, tmpGroupPtr->headerWindow,
  888.                 wishWindowContext, (caddr_t) aWindow);
  889.             XSaveContext(wishDisplay, tmpGroupPtr->headerWindow,
  890.                 wishGroupWindowContext, (caddr_t) tmpGroupPtr);
  891.             Sx_HandlerCreate(wishDisplay,
  892.                 tmpGroupPtr->headerWindow, KeyPressMask,
  893.                 WishEditRule, tmpGroupPtr->headerWindow);
  894.         } else {
  895.             /* is the window in a new place? */
  896.             if (tmpGroupPtr->entry_x != tmpGroupPtr->x ||
  897.                 tmpGroupPtr->entry_y != tmpGroupPtr->y ||
  898.                 tmpGroupPtr->entry_width !=
  899.                 aWindow->columnWidth) {
  900.             XWindowChanges    changes;
  901.  
  902.             tmpGroupPtr->entry_x = tmpGroupPtr->x;
  903.             tmpGroupPtr->entry_y = tmpGroupPtr->y;
  904.             tmpGroupPtr->entry_width = aWindow->columnWidth;
  905.             if (tmpGroupPtr->myColumn > 0) {
  906.                 changes.x = tmpGroupPtr->x;
  907.                 changes.y = tmpGroupPtr->y - 1;
  908.                 changes.width = aWindow->columnWidth - 1;
  909.                 changes.height = aWindow->rowHeight - 1;
  910.             } else {
  911.                 changes.x = tmpGroupPtr->x - 1;
  912.                 changes.y = tmpGroupPtr->y - 1;
  913.                 changes.width = aWindow->columnWidth;
  914.                 changes.height = aWindow->rowHeight - 1;
  915.             }
  916.             XConfigureWindow(wishDisplay,
  917.                 tmpGroupPtr->headerWindow,
  918.                 CWX | CWY | CWWidth | CWHeight, &changes);
  919.             }
  920.         }
  921.         /* in case it wasn't visible last time */
  922.         XMapWindow(wishDisplay, tmpGroupPtr->headerWindow);
  923.         numMappedHeaders++;    /* another header window mapped */
  924.         /*
  925.          * If fileList is NULL for this group, move to next group.
  926.          * If this new group isn't null, it means we need another space.
  927.          * Otherwise, we're finished with all the groups.
  928.          */
  929.         if (tmpFilePtr != NULL) {
  930.             continue;
  931.         }
  932.         /*
  933.           * The group's fileList is null, move on to new group.
  934.          * We can only get here with a null fileList if
  935.          * aWindow->hideEmptyGroupsP is FALSE.
  936.          */
  937.         tmpGroupPtr = tmpGroupPtr->nextPtr;
  938.         if (tmpGroupPtr == NULL) {
  939.             /* end of groups */
  940.             aWindow->lastElement = i + 1;
  941.             break;
  942.         }
  943.         /* leave tmpFilePtr NULL so that we know we're between groups */
  944.         spaceP = TRUE;
  945.         continue;
  946.         }
  947.         /* tmpFilePtr was not NULL, so set positions for the file name. */
  948.         tmpFilePtr->x = aWindow->columns[aWindow->usedCol].x;
  949.         tmpFilePtr->y = i * aWindow->rowHeight;
  950.         tmpFilePtr->myColumn = aWindow->usedCol;
  951.  
  952.         /* move on to next file */
  953.         tmpFilePtr = tmpFilePtr->nextPtr;
  954.         if (tmpFilePtr == NULL) {
  955.         /* end of group */
  956.         tmpGroupPtr = tmpGroupPtr->nextPtr;
  957.         if (tmpGroupPtr == NULL) {
  958.             /* end of groups */
  959.             aWindow->lastElement = i + 1;
  960.             break;
  961.         }
  962.         spaceP = TRUE;
  963.         }
  964.         continue;
  965.     }
  966.  
  967.     /* We're at the end of a column */
  968.     if (tmpGroupPtr == NULL) {
  969.         /* end of groups */
  970.         aWindow->usedCol++;        /* so it ends one bigger than used */
  971.         break;
  972.     }
  973.     }
  974.  
  975.     aWindow->usedCol--;        /* loop leaves it one too big */
  976. finished:
  977.  
  978.     /* mark the rest as not visible */
  979.     for ( ; tmpGroupPtr != NULL; tmpGroupPtr = tmpGroupPtr->nextPtr) {
  980.     /* If we stopped at a header, mark it as not visible */
  981.     if (tmpFilePtr == NULL) {
  982.         tmpGroupPtr->myColumn = -1;
  983.         tmpGroupPtr->x = tmpGroupPtr->y = -1;
  984.         if (tmpGroupPtr->headerWindow != UNINITIALIZED) {
  985.         XUnmapWindow(wishDisplay, tmpGroupPtr->headerWindow);
  986.         }
  987.         tmpFilePtr = tmpGroupPtr->fileList;
  988.     }
  989.  
  990.     for ( ; tmpFilePtr != NULL; tmpFilePtr = tmpFilePtr->nextPtr) {
  991.         tmpFilePtr->x = tmpFilePtr->y = -1;
  992.         tmpFilePtr->myColumn = -1;
  993.     }
  994.     }
  995.  
  996.     /* The number of the last element visible -- includes spaces and headers */
  997.     if (aWindow->lastElement == 0) {
  998.     aWindow->lastElement = aWindow->firstElement - 1 +
  999.         ((aWindow->usedCol + 1) * aWindow->numRows);
  1000.     } else {
  1001.     /* We're partway into a column, add on columns up to this one */
  1002.     aWindow->lastElement += aWindow->firstElement - 1 +
  1003.         (aWindow->usedCol * aWindow->numRows);
  1004.     }
  1005.  
  1006.     /* Get rid of extraneous redraw events from mapping(?) Sx entry windows. */
  1007.     for (i = 0; i < numMappedHeaders; i++) {
  1008.     XEvent    tossEvent;    /* dispose of this extra event */
  1009.  
  1010.     XCheckWindowEvent(wishDisplay, aWindow->displayWindow, ExposureMask,
  1011.         &tossEvent);
  1012.     }
  1013.  
  1014.     /* This causes WishRedraw() to be called, so the whole thing appears. */
  1015.     XMapWindow(wishDisplay, aWindow->displayWindow);
  1016.  
  1017. #ifdef SCROLL_DEBUG
  1018.     fprintf(stderr, "At end of WishSetPositions:\n");
  1019.     fprintf(stderr, "\tfirstElement is %d\n",
  1020.         aWindow->firstElement);
  1021.     fprintf(stderr, "\tlastElement is %d\n",
  1022.         aWindow->lastElement);
  1023.     fprintf(stderr, "\tnumElements is %d\n",
  1024.         aWindow->numElements);
  1025.     fprintf(stderr, "\tnumGroups is %d\n", aWindow->numGroups);
  1026.     fprintf(stderr, "\tnumRows is %d\n", aWindow->numRows);
  1027.     fprintf(stderr, "\tcolumns used is %d\n",
  1028.         aWindow->usedCol + 1);
  1029. #endif SCROLL_DEBUG
  1030.  
  1031.     return;
  1032. }
  1033.  
  1034.  
  1035. /*
  1036.  *----------------------------------------------------------------------
  1037.  *
  1038.  * WishRedraw --
  1039.  *
  1040.  *    Redraw display with positions already set.
  1041.  *
  1042.  * Results:
  1043.  *    None.
  1044.  *
  1045.  * Side effects:
  1046.  *    The display is redrawn.
  1047.  *
  1048.  *----------------------------------------------------------------------
  1049.  */
  1050. void
  1051. WishRedraw(aWindow)
  1052.     WishWindow    *aWindow;
  1053. {
  1054.     int    i;
  1055.     WishGroup    *tmpGroupPtr = NULL;
  1056.     WishFile    *tmpPtr = NULL;
  1057.     float    top, bottom;
  1058.     char    fields[MAXNAMLEN + (3 * 26) + 11];    /* space allocation
  1059.                              * described below */
  1060.     char    sorting[50];
  1061.     Boolean    somethingDrawnP = FALSE;
  1062.  
  1063.     if (aWindow->notifierP) {
  1064.     return;
  1065.     }
  1066.     strcpy(fields, "Filename");
  1067.     for (i = 0; i < aWindow->maxNameLength - strlen("Filename"); i++) {
  1068.     /* Very wasteful... */
  1069.     strcat(fields, " ");
  1070.     }
  1071.     if (aWindow->displayInstructions & WISH_ATIME_FIELD) {
  1072.     /* 24 chars needed for time, plus 2 spaces == 26 */
  1073.     strcat(fields, "  AccessTime              ");
  1074.     }
  1075.     if (aWindow->displayInstructions & WISH_MTIME_FIELD) {
  1076.     /* 24 chars needed for time, plus 2 spaces == 26 */
  1077.     strcat(fields, "  DataModifyTime          ");
  1078.     }
  1079.     if (aWindow->displayInstructions & WISH_DTIME_FIELD) {
  1080.     /* 24 chars needed for time, plus 2 spaces == 26 */
  1081.     /*
  1082.      * This is one of the few places where Descriptor isn't spelled out -
  1083.      * for space considerations.
  1084.      */
  1085.     strcat(fields, "  DescModifyTime          ");
  1086.     }
  1087.     if (aWindow->displayInstructions & WISH_SIZE_FIELD) {
  1088.     /* 9 chars needed for size, plus 2 spaces == 11 */
  1089.     strcat(fields, "      Bytes");
  1090.     }
  1091.  
  1092.     strcpy(sorting, "Sorted by:  ");
  1093.     if (aWindow->sortingInstructions & WISH_ALPHA_SORT) {
  1094.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  1095.         strcat(sorting, "Reverse Alphabet");
  1096.     } else {
  1097.         strcat(sorting, "Alphabet"); }
  1098.     }
  1099.     if (aWindow->sortingInstructions & WISH_ATIME_SORT) {
  1100.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  1101.         strcat(sorting, "Reverse AccessTime");
  1102.     } else {
  1103.         strcat(sorting, "AccessTime");
  1104.     }
  1105.     }
  1106.     if (aWindow->sortingInstructions & WISH_MTIME_SORT) {
  1107.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  1108.         strcat(sorting, "Reverse DataModifyTime");
  1109.     } else {
  1110.         strcat(sorting, "DataModifyTime");
  1111.     }
  1112.     }
  1113.     if (aWindow->sortingInstructions & WISH_DTIME_SORT) {
  1114.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  1115.         strcat(sorting, "Reverse DescriptorModifyTime");
  1116.     } else {
  1117.         strcat(sorting, "DescriptorModifyTime");
  1118.     }
  1119.     }
  1120.     if (aWindow->sortingInstructions & WISH_SIZE_SORT) {
  1121.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  1122.         strcat(sorting, "Reverse Size");
  1123.     } else {
  1124.         strcat(sorting, "Size");
  1125.     }
  1126.     }
  1127.  
  1128. #ifdef SCROLL_DEBUG
  1129.     fprintf(stderr, "Entered WishRedraw:\n");
  1130.     fprintf(stderr, "\tfirstElement is %d\n",
  1131.         aWindow->firstElement);
  1132.     fprintf(stderr, "\tlastElement is %d\n",
  1133.         aWindow->lastElement);
  1134.     fprintf(stderr, "\tnumElements is %d\n",
  1135.         aWindow->numElements);
  1136.     fprintf(stderr, "\tnumGroups is %d\n", aWindow->numGroups);
  1137. #endif SCROLL_DEBUG
  1138.  
  1139.     XClearArea(wishDisplay, aWindow->displayWindow, 0, 0, 0, 0, False);
  1140.  
  1141.     for (tmpGroupPtr = aWindow->groupList;
  1142.         tmpGroupPtr != NULL; tmpGroupPtr = tmpGroupPtr->nextPtr) {
  1143.     for (tmpPtr = tmpGroupPtr->fileList;
  1144.         tmpPtr != NULL; tmpPtr = tmpPtr->nextPtr) {
  1145.         WishRedrawFile(aWindow, tmpPtr);
  1146.         somethingDrawnP = TRUE;
  1147.     }
  1148.     }
  1149.     /*
  1150.      * Now draw the column dividers.
  1151.      */
  1152.     if (somethingDrawnP) {
  1153.     for (i = 1; i <= aWindow->usedCol; i++) {
  1154.         XDrawLine(wishDisplay, aWindow->displayWindow,
  1155.             aWindow->textGc,
  1156.             aWindow->columns[i].x, 0,
  1157.             aWindow->columns[i].x, aWindow->windowHeight);
  1158.     }
  1159.     }
  1160.     /*
  1161.      * Now set the scroll bar to match what will be displayed.
  1162.      */
  1163.     if (aWindow->numRows == 0) {
  1164.     top = 0.0;
  1165.     bottom = 1.0;
  1166.     } else {
  1167.     /*
  1168.      * First (last) entry divided by number of entries required.  (This
  1169.      * includes any displayed spaces and groups.)
  1170.      */
  1171.     top = ((float) aWindow->firstElement - 1) /
  1172.         ((float) aWindow->totalDisplayEntries);
  1173.     bottom = ((float) aWindow->lastElement) /
  1174.         ((float) aWindow->totalDisplayEntries);
  1175.     }
  1176. #ifdef SCROLL_DEBUG
  1177.     fprintf(stderr, "At end of WishRedraw:\n");
  1178.     fprintf(stderr, "\ttop is %f\n", top);
  1179.     fprintf(stderr, "\tbottom is %f\n", bottom);
  1180.     fprintf(stderr, "\tcalling SetRange.\n");
  1181. #endif SCROLL_DEBUG
  1182.  
  1183.     Sx_ScrollbarSetRange(wishDisplay, aWindow->scrollWindow, top, bottom);
  1184.     Sx_TitleMake(wishDisplay, aWindow->sortWindow, aWindow->fontPtr,
  1185.         aWindow->sortForeground, aWindow->sortBackground,
  1186.         aWindow->sortBackground, sorting, NULL, NULL);
  1187.     Sx_TitleMake(wishDisplay, aWindow->fieldsWindow, aWindow->fontPtr,
  1188.         aWindow->fieldsForeground, aWindow->fieldsBackground,
  1189.         aWindow->fieldsBackground, fields, NULL, NULL);
  1190.  
  1191.     return;
  1192. }
  1193.  
  1194.  
  1195.  
  1196. /*
  1197.  *----------------------------------------------------------------------
  1198.  *
  1199.  * WishRedrawFile --
  1200.  *
  1201.  *    Redraw a file entry.  Highlight with a box, or indicate that it is
  1202.  *    selected, if required.
  1203.  *
  1204.  * Results:
  1205.  *    None.
  1206.  *
  1207.  * Side effects:
  1208.  *    The file entry is redisplayed.
  1209.  *
  1210.  *----------------------------------------------------------------------
  1211.  */
  1212. void
  1213. WishRedrawFile(aWindow, filePtr)
  1214.     WishWindow    *aWindow;
  1215.     WishFile        *filePtr;
  1216. {
  1217.     char    *space = NULL;
  1218.     int        secondFieldStart;
  1219.     int        ascent;
  1220.     int        lbearing;    /* to indent string enough that we don't
  1221.                  * draw a box over its first char */
  1222.  
  1223.     if (aWindow->notifierP) {
  1224.     return;
  1225.     }
  1226.     if (filePtr->x == -1) {        /* is it visible? */
  1227.     return;
  1228.     }
  1229.     ascent = aWindow->fontPtr->ascent;
  1230.     lbearing =  -4;
  1231.     if ((aWindow->displayInstructions & ~WISH_NAME_FIELD) != 0) {
  1232.     space = (char *) malloc(aWindow->maxEntryWidth + 1 -
  1233.         aWindow->maxNameLength);
  1234.     space[0] = '\0';
  1235.     WishGetFileFields(aWindow, filePtr, &space);
  1236.     }
  1237.  
  1238.     secondFieldStart =
  1239.         WISH_CHAR_TO_WIDTH(aWindow->maxNameLength + 2, aWindow->fontPtr);
  1240.     if (filePtr->selectedP || filePtr->myGroupPtr->selectedP) {
  1241.     /* should highlight */
  1242.     XDrawImageString(wishDisplay, aWindow->displayWindow,
  1243.         aWindow->reverseGc, filePtr->x + -lbearing + 1,
  1244.         filePtr->y + ascent, filePtr->name, strlen(filePtr->name));
  1245.     if (space != NULL) {
  1246.         if (filePtr->lineP) {
  1247.         XDrawImageString(wishDisplay, aWindow->displayWindow,
  1248.             aWindow->reverseGc,
  1249.             filePtr->x + secondFieldStart,
  1250.             filePtr->y + ascent, space, strlen(space));
  1251.         } else {
  1252.         XDrawImageString(wishDisplay, aWindow->displayWindow,
  1253.             aWindow->textGc,
  1254.             filePtr->x + secondFieldStart,
  1255.             filePtr->y + ascent, space, strlen(space));
  1256.         }
  1257.     }
  1258.     } else {
  1259.     XDrawImageString(wishDisplay, aWindow->displayWindow, aWindow->textGc,
  1260.         filePtr->x + -lbearing + 1, filePtr->y + ascent, filePtr->name,
  1261.         strlen(filePtr->name)); 
  1262.     if (space != NULL) {
  1263.         XDrawImageString(wishDisplay, aWindow->displayWindow,
  1264.             aWindow->textGc, filePtr->x + secondFieldStart,
  1265.             filePtr->y + ascent, space, strlen(space));
  1266.     }
  1267.     }
  1268.  
  1269.     /* draw or undraw a box around it */
  1270.     {
  1271.     XPoint    vlist[5];
  1272.  
  1273.     vlist[0].x = filePtr->x + 1;
  1274.     vlist[0].y = filePtr->y + aWindow->rowHeight;
  1275.  
  1276.     /*
  1277.      * To make up for indentation of string by -lbearing amount.
  1278.      */
  1279.     vlist[1].x = -lbearing +
  1280.         WISH_CHAR_TO_WIDTH(aWindow->maxNameLength, aWindow->fontPtr);
  1281.     vlist[1].y = 0;
  1282.  
  1283.     vlist[2].x = 0;
  1284.     vlist[2].y = -(aWindow->rowHeight);
  1285.  
  1286.     vlist[3].x = -(vlist[1].x);
  1287.     vlist[3].y = 0;
  1288.  
  1289.     /* should be equal to first point - if not, make all rel. to origin. */
  1290.     vlist[4].x = 0;
  1291.     vlist[4].y = -(vlist[2].y);
  1292.  
  1293.     if (filePtr->highlightP) {
  1294.         /* should be selectionGc */
  1295.         XDrawLines(wishDisplay, aWindow->displayWindow,
  1296.             aWindow->textGc, vlist, 5, CoordModePrevious);
  1297.     } else {
  1298.         XDrawLines(wishDisplay, aWindow->displayWindow,
  1299.             aWindow->reverseGc, vlist, 5, CoordModePrevious);
  1300.     }
  1301.     }
  1302.     if (space != NULL) {
  1303.     free(space);
  1304.     }
  1305.  
  1306.     return;
  1307. }
  1308.  
  1309.  
  1310. /*
  1311.  *----------------------------------------------------------------------
  1312.  *
  1313.  * WishGetFileFields --
  1314.  *
  1315.  *    Get the additional fields to display for a file entry beyond the
  1316.  *    file name.
  1317.  *    If *buf is null, then allocate space for the string to return.
  1318.  *    Otherwise copy the return value into *buf.
  1319.  *
  1320.  * Results:
  1321.  *    None.
  1322.  *
  1323.  * Side effects:
  1324.  *    The file entry is redisplayed.
  1325.  *
  1326.  *----------------------------------------------------------------------
  1327.  */
  1328. void
  1329. WishGetFileFields(aWindow, filePtr, buf)
  1330.     WishWindow    *aWindow;
  1331.     WishFile        *filePtr;
  1332.     char        **buf;
  1333. {
  1334.     char    timeBuf[26];    /* 26 chars according to ctime man page */
  1335.     char    intBuf[CVT_INT_BUF_SIZE + 1]; /* const defined in my .h file */
  1336.     int        i;
  1337.     char    *space;
  1338.  
  1339.     /* What to do here? */
  1340.     if (*buf == NULL) {
  1341.     *buf = (char *) malloc(aWindow->maxEntryWidth + 1 -
  1342.         aWindow->maxNameLength);
  1343.     *buf[0] = '\0';
  1344.     }
  1345.     space = *buf;
  1346.     /* Any fields except for name? */
  1347.     if (!(aWindow->displayInstructions & (~WISH_NAME_FIELD))) {
  1348.     /* Could free up space from attrPtr field here, if I want. */
  1349.     return;
  1350.     }
  1351.     if (filePtr->attrPtr == NULL) {
  1352.     filePtr->attrPtr = (struct stat *) malloc(sizeof (struct stat));
  1353.     if (lstat(filePtr->name, filePtr->attrPtr) != 0) {
  1354.         sprintf(wishErrorMsg, "%s %s.  %s.",
  1355.             "Couldn't get attributes for file",
  1356.             filePtr->name,  "The file may no longer exist");
  1357.         aWindow->notifierP = TRUE;
  1358.         Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  1359.             wishErrorMsg, NULL, TRUE, "Continue",
  1360.             (char *) NULL);
  1361.         aWindow->notifierP = FALSE;
  1362.         bzero(filePtr->attrPtr, sizeof (struct stat)); 
  1363.         strcat(space, "  X  ");
  1364.         return;
  1365.     }
  1366.     }
  1367.     if (aWindow->displayInstructions & WISH_ATIME_FIELD) {
  1368.     /* 24 chars needed for time, plus 2 spaces == 26 */
  1369.     strcpy(timeBuf, ctime(&(filePtr->attrPtr->st_atime)));
  1370.     /* wasteful to do twice, I suppose */
  1371.     if (index(timeBuf, '\n') != NULL) {
  1372.         *(index(timeBuf, '\n')) = '\0';
  1373.     }
  1374.     strcat(space, timeBuf);
  1375.     strcat(space, "  ");
  1376.     }
  1377.     if (aWindow->displayInstructions & WISH_MTIME_FIELD) {
  1378.     /* 24 chars needed for time, plus 2 spaces */
  1379.     strcpy(timeBuf, ctime(&(filePtr->attrPtr->st_mtime)));
  1380.     /* wasteful to do twice, I suppose */
  1381.     if (index(timeBuf, '\n') != NULL) {
  1382.         *(index(timeBuf, '\n')) = '\0';
  1383.     }
  1384.     strcat(space, timeBuf);
  1385.     strcat(space, "  ");
  1386.     }
  1387.     if (aWindow->displayInstructions & WISH_DTIME_FIELD) {
  1388.     /* 24 chars needed for time, plus 2 spaces */
  1389.     strcpy(timeBuf, ctime(&(filePtr->attrPtr->st_ctime)));
  1390.     /* wasteful to do twice, I suppose */
  1391.     if (index(timeBuf, '\n') != NULL) {
  1392.         *(index(timeBuf, '\n')) = '\0';
  1393.     }
  1394.     strcat(space, timeBuf);
  1395.     strcat(space, "  ");
  1396.     }
  1397.     if (aWindow->displayInstructions & WISH_SIZE_FIELD) {
  1398.     /* 9 chars needed for size, plus 2 spaces */
  1399.     sprintf(intBuf, "%d", filePtr->attrPtr->st_size);
  1400.     for (i = 0; i < 9 - strlen(intBuf); i++) {
  1401.         strcat(space, " ");
  1402.     }
  1403.     strcat(space, intBuf);
  1404.     strcat(space, "  ");
  1405.     }
  1406. #ifdef NOTDEF
  1407.     if (aWindow->displayInstructions & WISH_OTHERSTUFF_FIELD) {
  1408.     /* 9 chars needed for size, plus 2 spaces */
  1409.     }
  1410. #endif NOTDEF
  1411.  
  1412.     return;
  1413. }
  1414.  
  1415.  
  1416. /*
  1417.  *----------------------------------------------------------------------
  1418.  *
  1419.  * WishSetWindowAndRowInfo --
  1420.  *
  1421.  *    Given the dimensions of the window, calculate
  1422.  *    the height of rows and the number of usable rows in the window,
  1423.  *    and set these fields (and the window dimension fields) in the
  1424.  *    given WishWindow structure.  The row height calculation is
  1425.  *    made relative to the current font height specified in the fontPtr
  1426.  *    field of the WishWindow structure.
  1427.  *
  1428.  * Results:
  1429.  *    None.
  1430.  *
  1431.  * Side effects:
  1432.  *    The fields in the WishWindow structure that are set are
  1433.  *    the rowHeight, numRows, windowHeight and windowWidth fields.
  1434.  *
  1435.  *----------------------------------------------------------------------
  1436.  */
  1437. void
  1438. WishSetWindowAndRowInfo(aWindow, height, width)
  1439.     WishWindow    *aWindow;
  1440.     int            height, width;
  1441. {
  1442.     aWindow->windowHeight = height;
  1443.     aWindow->windowWidth = width;
  1444.     aWindow->rowHeight = aWindow->fontPtr->max_bounds.ascent +
  1445.         aWindow->fontPtr->max_bounds.descent + WISH_ROW_SPACING;
  1446.     aWindow->numRows = aWindow->windowHeight / aWindow->rowHeight;
  1447.  
  1448.     return;
  1449. }
  1450.  
  1451.  
  1452.  
  1453. /*
  1454.  *----------------------------------------------------------------------
  1455.  *
  1456.  * WishRedrawGroup --
  1457.  *
  1458.  *    Not yet implemented.
  1459.  *
  1460.  * Results:
  1461.  *    None.
  1462.  *
  1463.  * Side effects:
  1464.  *    None.
  1465.  *
  1466.  *----------------------------------------------------------------------
  1467.  */
  1468. /*ARGSUSED*/
  1469. void
  1470. WishRedrawGroup(aWindow, groupPtr)
  1471.     WishWindow    *aWindow;
  1472.     WishGroup        *groupPtr;
  1473. {
  1474.     return;
  1475. }
  1476.  
  1477.  
  1478. /*
  1479.  *----------------------------------------------------------------------
  1480.  *
  1481.  * WishMapCoordsToFile --
  1482.  *
  1483.  *    Map the given coordinates to a file entry.  The mapping will work
  1484.  *    if the cursor is on the same line as a file entry.  It does not
  1485.  *    have to be directory over the file entry.
  1486.  *
  1487.  * Results:
  1488.  *    A pointer to the appropriate file entry, or NULL if there isn't
  1489.  *    one under the given coordinates.    
  1490.  *
  1491.  * Side effects:
  1492.  *    None.
  1493.  *
  1494.  *----------------------------------------------------------------------
  1495.  */
  1496. WishFile *
  1497. WishMapCoordsToFile(aWindow, x, y)
  1498.     WishWindow    *aWindow;
  1499.     int            x, y;
  1500. {
  1501.     WishGroup    *groupPtr;
  1502.     WishFile    *filePtr;
  1503.     int        ascent;
  1504.  
  1505.     ascent = aWindow->fontPtr->ascent;
  1506.     for (groupPtr = aWindow->groupList; groupPtr != NULL;
  1507.         groupPtr = groupPtr->nextPtr) {
  1508.     for (filePtr = groupPtr->fileList; filePtr != NULL;
  1509.         filePtr = filePtr->nextPtr) {
  1510.         if (filePtr->x == -1) {    /* off the display */
  1511.         continue;
  1512.         }
  1513.         if ((filePtr->x <= x && x <= filePtr->x + aWindow->columnWidth) &&
  1514.             (filePtr->y + ascent <= y && y <= filePtr->y + ascent +
  1515.             aWindow->rowHeight)) {
  1516.         return filePtr;
  1517.         }
  1518.     }
  1519.     }
  1520.  
  1521.     return NULL;
  1522. }
  1523.  
  1524.  
  1525. /*
  1526.  *----------------------------------------------------------------------
  1527.  *
  1528.  * WishMapCoordsToGroup --
  1529.  *
  1530.  *    Map the given coordinates to a group header.
  1531.  *
  1532.  * Results:
  1533.  *    A pointer to the appropriate group header, or NULL if there isn't
  1534.  *    one under the given coordinates.
  1535.  *
  1536.  * Side effects:
  1537.  *    None.
  1538.  *
  1539.  *----------------------------------------------------------------------
  1540.  */
  1541. WishGroup *
  1542. WishMapCoordsToGroup(aWindow, x, y)
  1543.     WishWindow    *aWindow;
  1544.     int            x, y;
  1545. {
  1546.     WishGroup    *groupPtr;
  1547.  
  1548.     for (groupPtr = aWindow->groupList; groupPtr != NULL;
  1549.         groupPtr = groupPtr->nextPtr) {
  1550.     if ((groupPtr->x <= x && x <= groupPtr->x + groupPtr->length) &&
  1551.         (groupPtr->y <= y && y <= groupPtr->y + aWindow->rowHeight)) {
  1552.         return groupPtr;
  1553.     }
  1554.     }
  1555.  
  1556.     return NULL;
  1557. }
  1558.  
  1559.  
  1560.  
  1561. /*
  1562.  *----------------------------------------------------------------------
  1563.  *
  1564.  * GetMaxEntryWidth --
  1565.  *
  1566.  *    Find the length of the longest column entry.
  1567.  *
  1568.  * Results:
  1569.  *    The length.
  1570.  *
  1571.  * Side effects:
  1572.  *    None.
  1573.  *
  1574.  *----------------------------------------------------------------------
  1575.  */
  1576. static int
  1577. GetMaxEntryWidth(aWindow)
  1578.     WishWindow    *aWindow;
  1579. {
  1580.     WishGroup    *tmpGroupPtr;
  1581.     WishFile    *tmpFilePtr;
  1582.     Boolean    getAttrsP = FALSE;
  1583.     int        charLength = 0;
  1584.     int        lbearing;
  1585.  
  1586.     if ((aWindow->displayInstructions & ~WISH_NAME_FIELD) != 0) {
  1587.     getAttrsP = TRUE;
  1588.     }
  1589.     lbearing = -4;
  1590.     aWindow->maxNameLength = 0;
  1591.     /*
  1592.      * Warning: this allocates space width for the rules, even if they
  1593.      * are hidden groups.
  1594.      */
  1595.     for (tmpGroupPtr = aWindow->groupList; tmpGroupPtr != NULL;
  1596.         tmpGroupPtr = tmpGroupPtr->nextPtr) {
  1597.     charLength = strlen(tmpGroupPtr->rule);
  1598.     tmpGroupPtr->length =
  1599.         XTextWidth(aWindow->fontPtr, tmpGroupPtr->rule, charLength);
  1600.     if (charLength > aWindow->maxNameLength) {
  1601.         aWindow->maxNameLength = charLength;
  1602.     }
  1603.     for (tmpFilePtr = tmpGroupPtr->fileList; tmpFilePtr != NULL;
  1604.         tmpFilePtr = tmpFilePtr->nextPtr) {
  1605.         charLength = strlen(tmpFilePtr->name);
  1606.         tmpFilePtr->length =
  1607.             XTextWidth(aWindow->fontPtr, tmpFilePtr->name, charLength);
  1608.         if (charLength > aWindow->maxNameLength) {
  1609.         aWindow->maxNameLength = charLength;
  1610.         }
  1611.     }
  1612.     }
  1613.     aWindow->maxEntryWidth = aWindow->maxNameLength;
  1614.     /* 2 chars for spaces */
  1615.     aWindow->maxEntryWidth += 2;
  1616.     if (getAttrsP) {
  1617.     if (aWindow->displayInstructions & WISH_ATIME_FIELD) {
  1618.         /* 24 chars needed for time, plus 2 spaces */
  1619.         aWindow->maxEntryWidth += 26;
  1620.     }
  1621.     if (aWindow->displayInstructions & WISH_MTIME_FIELD) {
  1622.         /* 24 chars needed for time, plus two spaces */
  1623.         aWindow->maxEntryWidth += 26;
  1624.     }
  1625.     if (aWindow->displayInstructions & WISH_DTIME_FIELD) {
  1626.         /* 24 chars needed for time, plus two spaces */
  1627.         aWindow->maxEntryWidth += 26;
  1628.     }
  1629.     if (aWindow->displayInstructions & WISH_SIZE_FIELD) {
  1630.         /* 9 chars needed for time, plus two spaces */
  1631.         aWindow->maxEntryWidth += 11;
  1632.     }
  1633. #ifdef NOTDEF
  1634.     /* what to do about owner sizes, groups, plus perm. display? */
  1635.     if (aWindow->displayInstructions & WISH_PERM_FIELD) {
  1636.         /* 1 chars needed for time, plus two spaces */
  1637.         aWindow->maxEntryWidth += 12;
  1638.     }
  1639.     if (aWindow->displayInstructions & WISH_TYPE_FIELD) {
  1640.         /* 1 chars needed for time, plus two spaces */
  1641.         aWindow->maxEntryWidth += 12;
  1642.     }
  1643. #endif NOTDEF
  1644.     }
  1645.  
  1646.     /*
  1647.      * Plus lbearing cause we want to indent string enough that we don't draw
  1648.      * a box around it.
  1649.      */
  1650.     return (-lbearing +
  1651.         WISH_CHAR_TO_WIDTH(aWindow->maxEntryWidth, aWindow->fontPtr));
  1652. }
  1653.  
  1654.  
  1655. /*
  1656.  *----------------------------------------------------------------------
  1657.  *
  1658.  * GetColumnWidthInfo --
  1659.  *
  1660.  *    Figure out the best fixed column width.  This includes the
  1661.  *    extra WISH_COLUMN_SPACING added.  Also figure out the number
  1662.  *    of columns.
  1663.  *
  1664.  * Results:
  1665.  *    None.
  1666.  *
  1667.  * Side effects:
  1668.  *    The columnWidth and numCols parameters are filled in with their values.
  1669.  *
  1670.  *----------------------------------------------------------------------
  1671.  */
  1672. static void
  1673. GetColumnWidthInfo(aWindow, maxEntryWidth, columnWidth, numCols)
  1674.     WishWindow    *aWindow;
  1675.     int            maxEntryWidth;
  1676.     int            *columnWidth;
  1677.     int            *numCols;
  1678. {
  1679.     int        numToDisplay;
  1680.     int        numColsRequired;
  1681.     int        widthLeft;
  1682.  
  1683.     if (maxEntryWidth < 0) {
  1684.     *columnWidth = GetMaxEntryWidth(aWindow) + WISH_COLUMN_SPACING;
  1685.     } else {
  1686.     *columnWidth = maxEntryWidth + WISH_COLUMN_SPACING;
  1687.     }
  1688.     *numCols = aWindow->windowWidth / *columnWidth;
  1689.     if (*numCols == 0) {
  1690.     return ;
  1691.     }
  1692.     numToDisplay = aWindow->totalDisplayEntries - aWindow->firstElement + 1;
  1693.     if (aWindow->numRows == 0) {
  1694.     return ;
  1695.     }
  1696.     numColsRequired = numToDisplay / aWindow->numRows;
  1697.     if (numToDisplay % aWindow->numRows != 0) {
  1698.     numColsRequired++;
  1699.     }
  1700.     if (numColsRequired < *numCols) {
  1701.     *numCols = numColsRequired;
  1702.     }
  1703.     if (*numCols == 0) {
  1704.     return ;
  1705.     }
  1706.     widthLeft = aWindow->windowWidth - (*numCols * *columnWidth);
  1707.     /*
  1708.      * This could allow the last column to fail to meet the scroll bar by
  1709.      * a number of pixels one less than the number of columns.
  1710.      * We also add 1 pixel here so that entry window borders will overlap
  1711.      * with the window borders if we start them at 1 pixel before the
  1712.      * actual text area.
  1713.      */
  1714.     *columnWidth += (widthLeft / *numCols) + 1;
  1715.  
  1716.     return ;
  1717. }
  1718.  
  1719.  
  1720. /*
  1721.  *----------------------------------------------------------------------
  1722.  *
  1723.  * FigureWindowSize --
  1724.  *
  1725.  *    Figure out a good window size.
  1726.  *
  1727.  * Results:
  1728.  *    None.
  1729.  *
  1730.  * Side effects:
  1731.  *    The window size changes and stuff is laid out again to match.
  1732.  *
  1733.  *----------------------------------------------------------------------
  1734.  */
  1735. static void
  1736. FigureWindowSize(aWindow, maxEntryWidth)
  1737.     WishWindow    *aWindow;
  1738.     int            maxEntryWidth;
  1739. {
  1740.     int        maxWidth;
  1741.     int        width, height;
  1742.     int        columnWidth, numCols, numRows, numColsRequired;
  1743.  
  1744.     columnWidth = maxEntryWidth;
  1745.  
  1746.     maxWidth = wishRootWidth / 8 * 7;
  1747.     width = maxWidth;
  1748.  
  1749.     numCols = width / (columnWidth + WISH_COLUMN_SPACING);
  1750.     if (numCols == 0) {
  1751.     /* just set to max size */
  1752.     }
  1753.  
  1754.     for ( ; ; ){
  1755.     /* Make it line up on column boundary -- no wasted space */
  1756.     width = numCols  * (columnWidth + WISH_COLUMN_SPACING); 
  1757.     height = width / 3 * 2;        /* 2/3's of width */
  1758.     numRows = height / aWindow->rowHeight;
  1759.     if (aWindow->numRows == 0) {
  1760.         /* just set to max size */
  1761.     }
  1762.     numColsRequired = aWindow->totalDisplayEntries / numRows;
  1763.  
  1764.     if (aWindow->totalDisplayEntries % numRows != 0) {
  1765.         numColsRequired++;
  1766.     }
  1767.     if (numColsRequired < numCols) {
  1768.         numCols--;
  1769.     } else {
  1770.         break;
  1771.     }
  1772.     }
  1773.     /* last shrinking may have gone too far since we shrank rows as well */
  1774.     if (numColsRequired > numCols && (width + columnWidth +
  1775.         WISH_COLUMN_SPACING <= maxWidth)) {
  1776.     numCols++;
  1777.     width += columnWidth + WISH_COLUMN_SPACING;
  1778.     /* leave height and numRows alone */
  1779.     }
  1780.     /*
  1781.      * This next will generate an ExposureMask event, but I'm not sure
  1782.      * yet just where it fit in, so I may change some things.
  1783.      * It is an incredible pain that I can't change the displayWindow
  1784.      * to the correct dimensions and have the packer know to resize the
  1785.      * parent window.  Right now I have to resize to parent (surrounding)
  1786.      * window to what I guess should be its size.  I can't
  1787.      * XGetGeometry() them here since they all seem to have a size of 1
  1788.      * in Sx until some event occurs...  IS THIS STILL TRUE IN X11???
  1789.      */
  1790.     /*
  1791.      * 2 titles, 2 regular bars, and 8 regular font heights for tx window.
  1792.      */
  1793.     if (aWindow->windowWidth != width || aWindow->windowHeight != height) {
  1794.     XWindowChanges    changes;
  1795.  
  1796.     changes.width = width + 1 + Sx_ScrollbarWidth();
  1797.     changes.height = height + 
  1798.         (2 * Sx_DefaultHeight(wishDisplay, aWindow->titleFontPtr))
  1799.         + 3 + (10 * Sx_DefaultHeight(wishDisplay, aWindow->fontPtr));
  1800.     XConfigureWindow(wishDisplay, aWindow->surroundingWindow,
  1801.         CWWidth | CWHeight, &changes);
  1802.     }
  1803.  
  1804.     return;
  1805. }
  1806.  
  1807.  
  1808. /*
  1809.  *----------------------------------------------------------------------
  1810.  *
  1811.  * WishDumpState --
  1812.  *
  1813.  *    Dump the contents of the group and file lists to stderr for debugging.
  1814.  *
  1815.  * Results:
  1816.  *    None.
  1817.  *
  1818.  * Side effects:
  1819.  *    Stuff gets printed to stderr.
  1820.  *
  1821.  *----------------------------------------------------------------------
  1822.  */
  1823. void
  1824. WishDumpState(aWindow)
  1825.     WishWindow    *aWindow;
  1826. {
  1827.     WishGroup    *tmpGroupPtr;
  1828.     WishFile    *tmpFilePtr;
  1829.  
  1830.     for (tmpGroupPtr = aWindow->groupList; tmpGroupPtr != NULL;
  1831.         tmpGroupPtr = tmpGroupPtr->nextPtr) {
  1832.     fprintf(stderr, "GROUP:\t%s\n", tmpGroupPtr->editHeader);
  1833.     for (tmpFilePtr = tmpGroupPtr->fileList; tmpFilePtr != NULL;
  1834.         tmpFilePtr = tmpFilePtr->nextPtr) {
  1835.         fprintf(stderr, "\t\t%s %s\n", tmpFilePtr->name,
  1836.             tmpFilePtr->attrPtr == NULL ? "NULL" : "attrs");
  1837.     }
  1838.     }
  1839.     return;
  1840. }
  1841. @
  1842.  
  1843.  
  1844. 1.5
  1845. log
  1846. @John changed mx/tx color interface, so I fixed wish.
  1847. @
  1848. text
  1849. @d18 1
  1850. a18 1
  1851. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishDisplay.c,v 1.4 89/01/11 11:30:59 mlgray Exp Locker: mgbaker $ SPRITE (Berkeley)";
  1852. d377 2
  1853. a378 1
  1854.         newWindow->scrollElevator, WishScroll, newWindow);
  1855. d416 3
  1856. a418 1
  1857.     info.titleStripe = newWindow->titleBackground;
  1858. @
  1859.  
  1860.  
  1861. 1.4
  1862. log
  1863. @Temporary checkin
  1864. @
  1865. text
  1866. @d18 1
  1867. a18 1
  1868. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishDisplay.c,v 1.3 88/11/03 19:44:38 mlgray Exp Locker: mlgray $ SPRITE (Berkeley)";
  1869. d411 5
  1870. @
  1871.  
  1872.  
  1873. 1.3
  1874. log
  1875. @Fixed many bugs - notifiers no longer trash the display.
  1876. @
  1877. text
  1878. @d18 1
  1879. a18 1
  1880. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishDisplay.c,v 1.2 88/11/02 14:49:54 mlgray Exp Locker: mlgray $ SPRITE (Berkeley)";
  1881. d404 4
  1882. d1733 3
  1883. d1742 1
  1884. a1742 1
  1885.         + 3 + (4 * Sx_DefaultHeight(wishDisplay, aWindow->fontPtr));
  1886. @
  1887.  
  1888.  
  1889. 1.2
  1890. log
  1891. @fsflat changed to wish
  1892. @
  1893. text
  1894. @d18 1
  1895. a18 1
  1896. static char rcsid[] = "$Header: wishDisplay.c,v 1.1 88/10/03 12:47:25 mlgray Exp $ SPRITE (Berkeley)";
  1897. d207 2
  1898. a649 1
  1899.  
  1900. d662 3
  1901. d1002 3
  1902. d1010 1
  1903. a1010 1
  1904.     if (aWindow->displayInstructions & FSFLAT_ATIME_FIELD) {
  1905. d1014 1
  1906. a1014 1
  1907.     if (aWindow->displayInstructions & FSFLAT_MTIME_FIELD) {
  1908. d1018 1
  1909. a1018 1
  1910.     if (aWindow->displayInstructions & FSFLAT_DTIME_FIELD) {
  1911. d1026 1
  1912. a1026 1
  1913.     if (aWindow->displayInstructions & FSFLAT_SIZE_FIELD) {
  1914. d1032 2
  1915. a1033 2
  1916.     if (aWindow->sortingInstructions & FSFLAT_ALPHA_SORT) {
  1917.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  1918. d1038 2
  1919. a1039 2
  1920.     if (aWindow->sortingInstructions & FSFLAT_ATIME_SORT) {
  1921.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  1922. d1045 2
  1923. a1046 2
  1924.     if (aWindow->sortingInstructions & FSFLAT_MTIME_SORT) {
  1925.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  1926. d1052 2
  1927. a1053 2
  1928.     if (aWindow->sortingInstructions & FSFLAT_DTIME_SORT) {
  1929.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  1930. d1059 2
  1931. a1060 2
  1932.     if (aWindow->sortingInstructions & FSFLAT_SIZE_SORT) {
  1933.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  1934. d1162 3
  1935. d1170 1
  1936. a1170 1
  1937.     if ((aWindow->displayInstructions & ~FSFLAT_NAME_FIELD) != 0) {
  1938. d1178 1
  1939. a1178 1
  1940.         FSFLAT_CHAR_TO_WIDTH(aWindow->maxNameLength + 2, aWindow->fontPtr);
  1941. d1192 1
  1942. a1192 1
  1943.             aWindow->reverseGc,
  1944. d1219 1
  1945. a1219 1
  1946.         FSFLAT_CHAR_TO_WIDTH(aWindow->maxNameLength, aWindow->fontPtr);
  1947. d1286 1
  1948. a1286 1
  1949.     if (!(aWindow->displayInstructions & (~FSFLAT_NAME_FIELD))) {
  1950. d1292 1
  1951. a1292 2
  1952.     if (lstat(filePtr->name, filePtr->attrPtr)
  1953.         != 0) {
  1954. d1296 1
  1955. d1300 2
  1956. a1301 1
  1957.         bzero(filePtr->attrPtr, sizeof (struct    stat)); 
  1958. d1306 1
  1959. a1306 1
  1960.     if (aWindow->displayInstructions & FSFLAT_ATIME_FIELD) {
  1961. d1316 1
  1962. a1316 1
  1963.     if (aWindow->displayInstructions & FSFLAT_MTIME_FIELD) {
  1964. d1326 1
  1965. a1326 1
  1966.     if (aWindow->displayInstructions & FSFLAT_DTIME_FIELD) {
  1967. d1336 1
  1968. a1336 1
  1969.     if (aWindow->displayInstructions & FSFLAT_SIZE_FIELD) {
  1970. d1346 1
  1971. a1346 1
  1972.     if (aWindow->displayInstructions & FSFLAT_OTHERSTUFF_FIELD) {
  1973. d1384 1
  1974. a1384 1
  1975.         aWindow->fontPtr->max_bounds.descent + FSFLAT_ROW_SPACING;
  1976. d1525 1
  1977. a1525 1
  1978.     if ((aWindow->displayInstructions & ~FSFLAT_NAME_FIELD) != 0) {
  1979. d1556 1
  1980. a1556 1
  1981.     if (aWindow->displayInstructions & FSFLAT_ATIME_FIELD) {
  1982. d1560 1
  1983. a1560 1
  1984.     if (aWindow->displayInstructions & FSFLAT_MTIME_FIELD) {
  1985. d1564 1
  1986. a1564 1
  1987.     if (aWindow->displayInstructions & FSFLAT_DTIME_FIELD) {
  1988. d1568 1
  1989. a1568 1
  1990.     if (aWindow->displayInstructions & FSFLAT_SIZE_FIELD) {
  1991. d1574 1
  1992. a1574 1
  1993.     if (aWindow->displayInstructions & FSFLAT_PERM_FIELD) {
  1994. d1578 1
  1995. a1578 1
  1996.     if (aWindow->displayInstructions & FSFLAT_TYPE_FIELD) {
  1997. d1590 1
  1998. a1590 1
  1999.         FSFLAT_CHAR_TO_WIDTH(aWindow->maxEntryWidth, aWindow->fontPtr));
  2000. d1600 1
  2001. a1600 1
  2002.  *    extra FSFLAT_COLUMN_SPACING added.  Also figure out the number
  2003. d1623 1
  2004. a1623 1
  2005.     *columnWidth = GetMaxEntryWidth(aWindow) + FSFLAT_COLUMN_SPACING;
  2006. d1625 1
  2007. a1625 1
  2008.     *columnWidth = maxEntryWidth + FSFLAT_COLUMN_SPACING;
  2009. d1688 1
  2010. a1688 1
  2011.     numCols = width / (columnWidth + FSFLAT_COLUMN_SPACING);
  2012. d1695 1
  2013. a1695 1
  2014.     width = numCols  * (columnWidth + FSFLAT_COLUMN_SPACING); 
  2015. d1714 1
  2016. a1714 1
  2017.         FSFLAT_COLUMN_SPACING <= maxWidth)) {
  2018. d1716 1
  2019. a1716 1
  2020.     width += columnWidth + FSFLAT_COLUMN_SPACING;
  2021. d1740 35
  2022. @
  2023.  
  2024.  
  2025. 1.1
  2026. log
  2027. @Initial revision
  2028. @
  2029. text
  2030. @d2 1
  2031. a2 1
  2032.  * fsflatDisplay.c --
  2033. d18 1
  2034. a18 1
  2035. static char rcsid[] = "$Header: fsflatDisplay.c,v 1.17 88/06/10 13:14:12 mlgray Exp $ SPRITE (Berkeley)";
  2036. d32 1
  2037. a32 1
  2038. #include "fsflatInt.h"
  2039. d53 18
  2040. a70 18
  2041.     {"bind",        FsflatBindCmd},
  2042.     {"changeDirectory",    FsflatChangeDirCmd},
  2043.     {"quit",        FsflatQuitCmd},
  2044.     {"close",        FsflatCloseCmd},
  2045.     {"redraw",        FsflatRedrawCmd},
  2046.     {"selection",    FsflatSelectionCmd},
  2047.     {"resize",        FsflatResizeCmd},
  2048.     {"toggleSelection",    FsflatToggleSelectionCmd},
  2049.     {"toggleSelEntry",    FsflatToggleSelEntryCmd},
  2050.     {"groupBind",    FsflatGroupBindCmd},
  2051.     {"open",        FsflatOpenCmd},
  2052.     {"sortFiles",    FsflatSortFilesCmd},
  2053.     {"setFields",    FsflatChangeFieldsCmd},
  2054.     {"defineGroup",    FsflatDefineGroupCmd},
  2055.     {"changeGroup",    FsflatChangeGroupCmd},
  2056.     {"pattern",        FsflatPatternCompareCmd},
  2057.     {"menu",        FsflatMenuCmd},
  2058.     {"exec",        FsflatExecCmd},
  2059. d77 1
  2060. a77 1
  2061. int    fsflatWindowCount = 0;
  2062. d92 1
  2063. a92 1
  2064.  * FsflatCreate --
  2065. d94 1
  2066. a94 1
  2067.  *    Create an fsflat window.
  2068. d97 1
  2069. a97 1
  2070.  *    A pointer to the created FsflatWindow structure, or NULL if the
  2071. d101 1
  2072. a101 1
  2073.  *    A new fsflat window will be created and displayed.
  2074. d105 3
  2075. a107 3
  2076. FsflatWindow *
  2077. FsflatCreate(aWindow, dir)
  2078.     FsflatWindow    *aWindow;    /* parent window */
  2079. d110 1
  2080. a110 1
  2081.     FsflatWindow    *newWindow;
  2082. d117 1
  2083. a117 1
  2084.     newWindow = (FsflatWindow *) malloc(sizeof (FsflatWindow));
  2085. d127 1
  2086. a127 1
  2087.         Sx_Panic(fsflatDisplay, newWindow->dir);
  2088. d140 1
  2089. a140 1
  2090.         sprintf(fsflatErrorMsg,
  2091. d143 1
  2092. a143 1
  2093.         Sx_Panic(fsflatDisplay, fsflatErrorMsg);
  2094. d156 2
  2095. a157 2
  2096.         sprintf(fsflatErrorMsg, "%s is not a directory", newWindow->dir);
  2097.         Sx_Panic(fsflatDisplay, fsflatErrorMsg);
  2098. d167 1
  2099. a167 1
  2100.         sprintf(fsflatErrorMsg,
  2101. d169 1
  2102. a169 1
  2103.         Sx_Panic(fsflatDisplay, fsflatErrorMsg);
  2104. d176 1
  2105. a176 1
  2106.     strcpy(fsflatCurrentDirectory, newWindow->dir);
  2107. d216 2
  2108. a217 2
  2109.     newWindow->surroundingWindow = XCreateSimpleWindow(fsflatDisplay,
  2110.         DefaultRootWindow(fsflatDisplay), sizeHints.x, sizeHints.y,
  2111. d222 1
  2112. a222 1
  2113.         Sx_Panic(fsflatDisplay, "Couldn't create a new window.");
  2114. d227 3
  2115. d234 1
  2116. a234 1
  2117.     newWindow->textGc = XCreateGC(fsflatDisplay, newWindow->surroundingWindow,
  2118. d240 1
  2119. a240 1
  2120.     newWindow->reverseGc = XCreateGC(fsflatDisplay,
  2121. d251 1
  2122. a251 1
  2123.     newWindow->titleWindow = Sx_CreatePacked(fsflatDisplay,
  2124. d253 1
  2125. a253 1
  2126.         SX_TOP, Sx_DefaultHeight(fsflatDisplay, newWindow->titleFontPtr),
  2127. d258 1
  2128. a258 1
  2129.         Sx_Panic(fsflatDisplay, "Couldn't create title window.");
  2130. d264 1
  2131. a264 1
  2132.     Sx_EntryMake(fsflatDisplay, newWindow->titleWindow, "Directory:  ",
  2133. d269 1
  2134. a269 1
  2135.     newWindow->txOutsideWindow = Sx_CreatePacked(fsflatDisplay,
  2136. d271 1
  2137. a271 1
  2138.         SX_BOTTOM, 8 * Sx_DefaultHeight(fsflatDisplay, newWindow->fontPtr),
  2139. d279 1
  2140. a279 1
  2141.     if (XGetGeometry(fsflatDisplay, newWindow->txOutsideWindow, &dummy1,
  2142. d281 1
  2143. a281 1
  2144.         Sx_Panic(fsflatDisplay, "Couldn't get tx window geometry.");
  2145. d287 1
  2146. a287 1
  2147.     newWindow->divider1Window = Sx_CreatePacked(fsflatDisplay,
  2148. d292 1
  2149. a292 1
  2150.         Sx_Panic(fsflatDisplay,
  2151. d299 1
  2152. a299 1
  2153.     newWindow->menuBar = Sx_CreatePacked(fsflatDisplay,
  2154. d301 1
  2155. a301 1
  2156.         Sx_DefaultHeight(fsflatDisplay, newWindow->titleFontPtr), 0, 0,
  2157. d304 1
  2158. a304 1
  2159.     newWindow->divider2Window = Sx_CreatePacked(fsflatDisplay,
  2160. d309 1
  2161. a309 1
  2162.         Sx_Panic(fsflatDisplay,
  2163. d316 1
  2164. a316 1
  2165.     newWindow->sortWindow = Sx_TitleCreate(fsflatDisplay,
  2166. d318 1
  2167. a318 1
  2168.     SX_TOP, Sx_DefaultHeight(fsflatDisplay, newWindow->fontPtr), 0,
  2169. d324 1
  2170. a324 1
  2171.         Sx_Panic(fsflatDisplay, "Couldn't create the sort window.");
  2172. d329 1
  2173. a329 1
  2174.     newWindow->divider3Window = Sx_CreatePacked(fsflatDisplay,
  2175. d334 1
  2176. a334 1
  2177.         Sx_Panic(fsflatDisplay,
  2178. d341 1
  2179. a341 1
  2180.     newWindow->fieldsWindow = Sx_TitleCreate(fsflatDisplay,
  2181. d343 1
  2182. a343 1
  2183.     SX_TOP, Sx_DefaultHeight(fsflatDisplay, newWindow->fontPtr), 0,
  2184. d349 1
  2185. a349 1
  2186.         Sx_Panic(fsflatDisplay, "Couldn't create the fields window.");
  2187. d355 1
  2188. a355 1
  2189.     newWindow->divider4Window = Sx_CreatePacked(fsflatDisplay,
  2190. d360 1
  2191. a360 1
  2192.         Sx_Panic(fsflatDisplay,
  2193. d371 1
  2194. a371 1
  2195.     newWindow->scrollWindow = Sx_ScrollbarCreate(fsflatDisplay,
  2196. d375 1
  2197. a375 1
  2198.         newWindow->scrollElevator, FsflatScroll, newWindow);
  2199. d378 1
  2200. a378 1
  2201.         Sx_Panic(fsflatDisplay, "Couldn't create the scroll bar.");
  2202. d384 1
  2203. a384 1
  2204.     newWindow->divider5Window = Sx_CreatePacked(fsflatDisplay,
  2205. d389 1
  2206. a389 1
  2207.         Sx_Panic(fsflatDisplay,
  2208. d402 1
  2209. a402 1
  2210.     info.height = 4 * Sx_DefaultHeight(fsflatDisplay, newWindow->fontPtr);
  2211. d407 2
  2212. a408 2
  2213.     XStoreName(fsflatDisplay, newWindow->txOutsideWindow, info.title);
  2214.     Tx_Make(fsflatDisplay, newWindow->txOutsideWindow, &info, Tx_InputProc,
  2215. d410 1
  2216. a410 1
  2217.     Tx_Shell(fsflatDisplay, newWindow->txOutsideWindow, &info, args);
  2218. d412 1
  2219. a412 1
  2220.     newWindow->divider6Window = Sx_CreatePacked(fsflatDisplay,
  2221. d418 1
  2222. a418 1
  2223.         Sx_Panic(fsflatDisplay,
  2224. d426 1
  2225. a426 1
  2226.     newWindow->displayWindow = Sx_CreatePacked(fsflatDisplay,
  2227. d432 1
  2228. a432 1
  2229.         Sx_Panic(fsflatDisplay, "Couldn't create the display window.");
  2230. d437 2
  2231. a438 2
  2232.         XDestroySubwindows(fsflatDisplay, newWindow->surroundingWindow);
  2233.         XDestroyWindow(fsflatDisplay, newWindow->surroundingWindow);
  2234. d446 1
  2235. a446 1
  2236.      * structure into the fsflatWindowContext.
  2237. d448 3
  2238. a450 3
  2239.     fsflatWindowCount++;
  2240.     XSaveContext(fsflatDisplay, newWindow->surroundingWindow,
  2241.         (caddr_t) fsflatWindowContext, newWindow);
  2242. d454 1
  2243. a454 1
  2244.      * FsflatInit() will map the surrounding window.  It may first change
  2245. d457 1
  2246. a457 1
  2247.     FsflatInit(newWindow);
  2248. d460 1
  2249. a460 1
  2250.      * FsflatSetPositions() and FsflatRedraw() will be called as a result
  2251. d466 2
  2252. a467 2
  2253.     Sx_HandlerCreate(fsflatDisplay, newWindow->surroundingWindow,
  2254.         EnterWindowMask, FsflatHandleEnterEvent, newWindow);
  2255. d472 2
  2256. a473 2
  2257.     Sx_HandlerCreate(fsflatDisplay, newWindow->displayWindow, ButtonPressMask
  2258.         | PointerMotionMask | LeaveWindowMask, FsflatMouseEvent,
  2259. d479 2
  2260. a480 2
  2261.     Sx_HandlerCreate(fsflatDisplay, newWindow->titleWindow, KeyPressMask,
  2262.         FsflatEditDir, newWindow->surroundingWindow);
  2263. d484 1
  2264. a484 1
  2265.      * Add dir to fsflat's list.  Use windowID to match this dir for this
  2266. d489 2
  2267. a490 2
  2268.     Sx_Panic(fsflatDisplay,
  2269.         "File system monitor failed in FsflatCreate().");
  2270. d500 1
  2271. a500 1
  2272.  * FsflatInit --
  2273. d513 2
  2274. a514 2
  2275. FsflatInit(aWindow)
  2276.     FsflatWindow    *aWindow;    /* info for this instance of display */
  2277. d522 4
  2278. a525 4
  2279.     XQueryColor(fsflatDisplay, DefaultColormap(fsflatDisplay,
  2280.         DefaultScreen(fsflatDisplay)), &cursorForeground);
  2281.     XQueryColor(fsflatDisplay, DefaultColormap(fsflatDisplay,
  2282.         DefaultScreen(fsflatDisplay)), &cursorBackground);
  2283. d527 2
  2284. a528 2
  2285.     source = XCreateBitmapFromData(fsflatDisplay,
  2286.         DefaultRootWindow(fsflatDisplay), flatCursor_bits,
  2287. d530 1
  2288. a530 1
  2289.     flatCursor = XCreatePixmapCursor(fsflatDisplay, source, None,
  2290. d533 1
  2291. a533 1
  2292.     XFreePixmap(fsflatDisplay, source);
  2293. d536 1
  2294. a536 1
  2295.     XDefineCursor(fsflatDisplay, aWindow->displayWindow, flatCursor);
  2296. d542 2
  2297. a543 2
  2298.     source = XCreateBitmapFromData(fsflatDisplay,
  2299.         DefaultRootWindow(fsflatDisplay), waitCursor_bits,
  2300. d545 1
  2301. a545 1
  2302.     waitCursor = XCreatePixmapCursor(fsflatDisplay, source, None,
  2303. d548 1
  2304. a548 1
  2305.     XFreePixmap(fsflatDisplay, source);
  2306. d554 1
  2307. a554 1
  2308.     if (XGetGeometry(fsflatDisplay, aWindow->displayWindow, &dummy1,
  2309. d556 1
  2310. a556 1
  2311.         Sx_Panic(fsflatDisplay, "Couldn't get display window geometry.");
  2312. d558 1
  2313. a558 1
  2314.     FsflatSetWindowAndRowInfo(aWindow, height, width);
  2315. d571 1
  2316. a571 1
  2317.     aWindow->columns = (FsflatColumn *) malloc(8 * sizeof (FsflatColumn));
  2318. d574 1
  2319. a574 1
  2320.     if (fsflatResizeP) {
  2321. d579 1
  2322. a579 1
  2323.     if (fsflatPickSizeP) {
  2324. d584 1
  2325. a584 1
  2326.     if (fsflatShowEmptyGroupsP) {
  2327. d592 1
  2328. a592 1
  2329.     FsflatCmdTableInit(&(aWindow->cmdTable), &(aWindow->interp),
  2330. d595 1
  2331. a595 1
  2332.     FsflatSourceConfig(aWindow);
  2333. d604 1
  2334. a604 1
  2335.     XMapWindow(fsflatDisplay, aWindow->surroundingWindow);
  2336. d606 1
  2337. a606 1
  2338.     Sx_HandlerCreate(fsflatDisplay, aWindow->displayWindow,
  2339. d608 5
  2340. a612 5
  2341.         FsflatHandleDrawingEvent, (ClientData) aWindow);
  2342.     Sx_HandlerCreate(fsflatDisplay, aWindow->displayWindow, KeyPressMask,
  2343.         FsflatKeyProc, (ClientData) aWindow);
  2344.     Sx_HandlerCreate(fsflatDisplay, aWindow->menuBar, EnterWindowMask,
  2345.         FsflatMenuEntryProc, (ClientData) aWindow);
  2346. d621 1
  2347. a621 1
  2348.  * FsflatSetPositions --
  2349. d636 2
  2350. a637 2
  2351. FsflatSetPositions(aWindow)
  2352.     FsflatWindow    *aWindow;
  2353. d639 3
  2354. a641 3
  2355.     FsflatGroup        *tmpGroupPtr = NULL;
  2356.     FsflatFile        *tmpFilePtr = NULL;
  2357.     FsflatColumn    *newColumns;
  2358. d650 1
  2359. a650 1
  2360.     fprintf(stderr, "Entered FsflatSetPositions:\n");
  2361. d662 2
  2362. a663 2
  2363.     sprintf(fsflatErrorMsg,
  2364.         "Entered FsflatSetPositions with firstElement = %d",
  2365. d665 1
  2366. a665 1
  2367.     Sx_Panic(fsflatDisplay, fsflatErrorMsg);
  2368. d669 1
  2369. a669 1
  2370.      * window will be remapped later causing FsflatRedraw() to be called.
  2371. d671 1
  2372. a671 1
  2373.     XUnmapWindow(fsflatDisplay, aWindow->displayWindow);
  2374. d685 2
  2375. a686 2
  2376.     newColumns = (FsflatColumn *)
  2377.         malloc(aWindow->maxColumns * 2 * sizeof (FsflatColumn));
  2378. d712 1
  2379. a712 1
  2380.         XUnmapWindow(fsflatDisplay, tmpGroupPtr->headerWindow);
  2381. d773 1
  2382. a773 1
  2383.             XUnmapWindow(fsflatDisplay, tmpGroupPtr->headerWindow);
  2384. d797 1
  2385. a797 1
  2386.                 Sx_EntryCreate(fsflatDisplay,
  2387. d808 1
  2388. a808 1
  2389.                 Sx_EntryCreate(fsflatDisplay,
  2390. d819 1
  2391. a819 1
  2392.             Sx_Panic(fsflatDisplay,
  2393. d822 5
  2394. a826 5
  2395.             XSaveContext(fsflatDisplay, tmpGroupPtr->headerWindow,
  2396.                 fsflatWindowContext, (caddr_t) aWindow);
  2397.             XSaveContext(fsflatDisplay, tmpGroupPtr->headerWindow,
  2398.                 fsflatGroupWindowContext, (caddr_t) tmpGroupPtr);
  2399.             Sx_HandlerCreate(fsflatDisplay,
  2400. d828 1
  2401. a828 1
  2402.                 FsflatEditRule, tmpGroupPtr->headerWindow);
  2403. d851 1
  2404. a851 1
  2405.             XConfigureWindow(fsflatDisplay,
  2406. d857 1
  2407. a857 1
  2408.         XMapWindow(fsflatDisplay, tmpGroupPtr->headerWindow);
  2409. d920 1
  2410. a920 1
  2411.         XUnmapWindow(fsflatDisplay, tmpGroupPtr->headerWindow);
  2412. d945 1
  2413. a945 1
  2414.     XCheckWindowEvent(fsflatDisplay, aWindow->displayWindow, ExposureMask,
  2415. d949 2
  2416. a950 2
  2417.     /* This causes FsflatRedraw() to be called, so the whole thing appears. */
  2418.     XMapWindow(fsflatDisplay, aWindow->displayWindow);
  2419. d953 1
  2420. a953 1
  2421.     fprintf(stderr, "At end of FsflatSetPositions:\n");
  2422. d973 1
  2423. a973 1
  2424.  * FsflatRedraw --
  2425. d986 2
  2426. a987 2
  2427. FsflatRedraw(aWindow)
  2428.     FsflatWindow    *aWindow;
  2429. d990 2
  2430. a991 2
  2431.     FsflatGroup    *tmpGroupPtr = NULL;
  2432.     FsflatFile    *tmpPtr = NULL;
  2433. d1061 1
  2434. a1061 1
  2435.     fprintf(stderr, "Entered FsflatRedraw:\n");
  2436. d1071 1
  2437. a1071 1
  2438.     XClearArea(fsflatDisplay, aWindow->displayWindow, 0, 0, 0, 0, False);
  2439. d1077 1
  2440. a1077 1
  2441.         FsflatRedrawFile(aWindow, tmpPtr);
  2442. d1086 1
  2443. a1086 1
  2444.         XDrawLine(fsflatDisplay, aWindow->displayWindow,
  2445. d1109 1
  2446. a1109 1
  2447.     fprintf(stderr, "At end of FsflatRedraw:\n");
  2448. d1115 2
  2449. a1116 2
  2450.     Sx_ScrollbarSetRange(fsflatDisplay, aWindow->scrollWindow, top, bottom);
  2451.     Sx_TitleMake(fsflatDisplay, aWindow->sortWindow, aWindow->fontPtr,
  2452. d1119 1
  2453. a1119 1
  2454.     Sx_TitleMake(fsflatDisplay, aWindow->fieldsWindow, aWindow->fontPtr,
  2455. d1131 1
  2456. a1131 1
  2457.  * FsflatRedrawFile --
  2458. d1145 3
  2459. a1147 3
  2460. FsflatRedrawFile(aWindow, filePtr)
  2461.     FsflatWindow    *aWindow;
  2462.     FsflatFile        *filePtr;
  2463. d1152 2
  2464. d1159 1
  2465. d1164 1
  2466. a1164 1
  2467.     FsflatGetFileFields(aWindow, filePtr, &space);
  2468. d1171 3
  2469. a1173 3
  2470.     XDrawImageString(fsflatDisplay, aWindow->displayWindow,
  2471.         aWindow->reverseGc, filePtr->x + 1, filePtr->y + ascent,
  2472.         filePtr->name, strlen(filePtr->name));
  2473. d1176 1
  2474. a1176 1
  2475.         XDrawImageString(fsflatDisplay, aWindow->displayWindow,
  2476. d1181 1
  2477. a1181 1
  2478.         XDrawImageString(fsflatDisplay, aWindow->displayWindow,
  2479. d1188 2
  2480. a1189 2
  2481.     XDrawImageString(fsflatDisplay, aWindow->displayWindow, aWindow->textGc,
  2482.         filePtr->x + 1, filePtr->y + ascent, filePtr->name,
  2483. d1192 1
  2484. a1192 1
  2485.         XDrawImageString(fsflatDisplay, aWindow->displayWindow,
  2486. d1205 4
  2487. a1208 1
  2488.     vlist[1].x =
  2489. d1224 1
  2490. a1224 1
  2491.         XDrawLines(fsflatDisplay, aWindow->displayWindow,
  2492. d1227 1
  2493. a1227 1
  2494.         XDrawLines(fsflatDisplay, aWindow->displayWindow,
  2495. d1242 1
  2496. a1242 1
  2497.  * FsflatGetFileFields --
  2498. d1258 3
  2499. a1260 3
  2500. FsflatGetFileFields(aWindow, filePtr, buf)
  2501.     FsflatWindow    *aWindow;
  2502.     FsflatFile        *filePtr;
  2503. d1284 1
  2504. a1284 1
  2505.         sprintf(fsflatErrorMsg, "%s %s.  %s.",
  2506. d1287 2
  2507. a1288 2
  2508.         Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2509.             fsflatErrorMsg, NULL, TRUE, "Continue",
  2510. d1347 1
  2511. a1347 1
  2512.  * FsflatSetWindowAndRowInfo --
  2513. d1352 1
  2514. a1352 1
  2515.  *    given FsflatWindow structure.  The row height calculation is
  2516. d1354 1
  2517. a1354 1
  2518.  *    field of the FsflatWindow structure.
  2519. d1360 1
  2520. a1360 1
  2521.  *    The fields in the FsflatWindow structure that are set are
  2522. d1366 2
  2523. a1367 2
  2524. FsflatSetWindowAndRowInfo(aWindow, height, width)
  2525.     FsflatWindow    *aWindow;
  2526. d1384 1
  2527. a1384 1
  2528.  * FsflatRedrawGroup --
  2529. d1398 3
  2530. a1400 3
  2531. FsflatRedrawGroup(aWindow, groupPtr)
  2532.     FsflatWindow    *aWindow;
  2533.     FsflatGroup        *groupPtr;
  2534. d1409 1
  2535. a1409 1
  2536.  * FsflatMapCoordsToFile --
  2537. d1424 3
  2538. a1426 3
  2539. FsflatFile *
  2540. FsflatMapCoordsToFile(aWindow, x, y)
  2541.     FsflatWindow    *aWindow;
  2542. d1429 2
  2543. a1430 2
  2544.     FsflatGroup    *groupPtr;
  2545.     FsflatFile    *filePtr;
  2546. d1456 1
  2547. a1456 1
  2548.  * FsflatMapCoordsToGroup --
  2549. d1469 3
  2550. a1471 3
  2551. FsflatGroup *
  2552. FsflatMapCoordsToGroup(aWindow, x, y)
  2553.     FsflatWindow    *aWindow;
  2554. d1474 1
  2555. a1474 1
  2556.     FsflatGroup    *groupPtr;
  2557. d1506 1
  2558. a1506 1
  2559.     FsflatWindow    *aWindow;
  2560. d1508 2
  2561. a1509 2
  2562.     FsflatGroup    *tmpGroupPtr;
  2563.     FsflatFile    *tmpFilePtr;
  2564. d1512 1
  2565. d1517 1
  2566. d1574 6
  2567. a1579 1
  2568.     return FSFLAT_CHAR_TO_WIDTH(aWindow->maxEntryWidth, aWindow->fontPtr);
  2569. d1602 1
  2570. a1602 1
  2571.     FsflatWindow    *aWindow;
  2572. d1665 1
  2573. a1665 1
  2574.     FsflatWindow    *aWindow;
  2575. d1674 1
  2576. a1674 1
  2577.     maxWidth = fsflatRootWidth / 8 * 7;
  2578. d1723 3
  2579. a1725 3
  2580.         (2 * Sx_DefaultHeight(fsflatDisplay, aWindow->titleFontPtr))
  2581.         + 3 + (4 * Sx_DefaultHeight(fsflatDisplay, aWindow->fontPtr));
  2582.     XConfigureWindow(fsflatDisplay, aWindow->surroundingWindow,
  2583. @
  2584.